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
107
108
109
110
111
112
113
114
115
116
117
118
|
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.document;
import com.yahoo.document.datatypes.FieldValue;
import com.yahoo.document.datatypes.IntegerFieldValue;
import com.yahoo.document.datatypes.Struct;
import com.yahoo.geo.DegreesParser;
import com.yahoo.document.serialization.XmlStream;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
/**
* @author Simon Thoresen Hult
*/
public final class PositionDataType {
public static final StructDataType INSTANCE = newInstance();
public static final String STRUCT_NAME = "position";
public static final String FIELD_X = "x";
public static final String FIELD_Y = "y";
private static final Field FFIELD_X = INSTANCE.getField(FIELD_X);
private static final Field FFIELD_Y = INSTANCE.getField(FIELD_Y);
private static final DecimalFormat degreeFmt;
static {
degreeFmt = new DecimalFormat("0.0#####", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
degreeFmt.setMinimumIntegerDigits(1);
degreeFmt.setMinimumFractionDigits(1);
degreeFmt.setMaximumFractionDigits(6);
}
static String fmtD(double degrees) {
return degreeFmt.format(degrees);
}
private PositionDataType() {
// unreachable
}
public static String renderAsString(Struct pos) {
StringBuilder buf = new StringBuilder();
double ns = getYValue(pos).getInteger() / 1.0e6;
double ew = getXValue(pos).getInteger() / 1.0e6;
buf.append(ns < 0 ? "S" : "N");
buf.append(fmtD(ns < 0 ? (-ns) : ns));
buf.append(";");
buf.append(ew < 0 ? "W" : "E");
buf.append(fmtD(ew < 0 ? (-ew) : ew));
return buf.toString();
}
public static void renderXml(Struct pos, XmlStream target) {
target.addContent(renderAsString(pos));
}
public static Struct valueOf(Integer x, Integer y) {
Struct ret = new Struct(INSTANCE);
ret.setFieldValue(FIELD_X, x != null ? new IntegerFieldValue(x) : null);
ret.setFieldValue(FIELD_Y, y != null ? new IntegerFieldValue(y) : null);
return ret;
}
public static Struct fromLong(long val) {
return valueOf((int)(val >> 32), (int)val);
}
public static Struct fromString(String str) {
try {
DegreesParser d = new DegreesParser(str);
return valueOf((int)(d.longitude * 1000000), (int)(d.latitude * 1000000));
} catch (IllegalArgumentException e) {
try {
String[] arr = str.split(";");
if (arr.length == 2) {
int x = Integer.parseInt(arr[0]);
int y = Integer.parseInt(arr[1]);
return valueOf(x, y);
}
} catch (NumberFormatException nfe) {
// empty
}
throw new IllegalArgumentException("Could not parse '"+str+"' as geo coordinates: "+e.getMessage());
}
}
public static IntegerFieldValue getXValue(FieldValue pos) {
return Struct.getFieldValue(pos, INSTANCE, FFIELD_X, IntegerFieldValue.class);
}
public static IntegerFieldValue getYValue(FieldValue pos) {
return Struct.getFieldValue(pos, INSTANCE, FFIELD_Y, IntegerFieldValue.class);
}
public static String getZCurveFieldName(String fieldName) {
return fieldName + "_zcurve";
}
public static String getPositionSummaryFieldName(String fieldName) {
// TODO for 6.0, rename to _position to use a field name that is actually legal
return fieldName + ".position";
}
public static String getDistanceSummaryFieldName(String fieldName) {
// TODO for 6.0, rename to _distance to use a field name that is actually legal
return fieldName + ".distance";
}
private static StructDataType newInstance() {
StructDataType ret = new StructDataType(STRUCT_NAME);
ret.addField(new Field(FIELD_X, DataType.INT));
ret.addField(new Field(FIELD_Y, DataType.INT));
return ret;
}
}
|