diff options
author | Arne H Juul <arnej@yahooinc.com> | 2021-11-25 14:06:13 +0000 |
---|---|---|
committer | Arne H Juul <arnej@yahooinc.com> | 2021-11-25 14:06:13 +0000 |
commit | 82175a16fe262783715d1984ee35fdcf8141783f (patch) | |
tree | 2e71c9604fff4afe80aedd84946fa0043f6ed0b8 /document | |
parent | 53599cea91b8adad824a100b3ff42a5b84a29368 (diff) |
accept 'lat'/'lng' JSON for positions
Diffstat (limited to 'document')
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()); |