* If the first character is not a letter then it's assumed to be a point or rectangle. If that
* doesn't work out then an {@link com.spatial4j.core.exception.InvalidShapeException} is thrown.
*/
public static Shape readShapeOrNull(String str, SpatialContext ctx) throws InvalidShapeException {
if (str == null || str.length() == 0) {
throw new InvalidShapeException(str);
}
if (Character.isLetter(str.charAt(0))) {
if (str.startsWith("Circle(") || str.startsWith("CIRCLE(")) {
int idx = str.lastIndexOf(')');
if (idx > 0) {
String body = str.substring("Circle(".length(), idx);
StringTokenizer st = new StringTokenizer(body, " ");
String token = st.nextToken();
Point pt;
if (token.indexOf(',') != -1) {
pt = readLatCommaLonPoint(token, ctx);
} else {
double x = Double.parseDouble(token);
double y = Double.parseDouble(st.nextToken());
pt = ctx.makePoint(x, y);
}
Double d = null;
String arg = st.nextToken();
idx = arg.indexOf('=');
if (idx > 0) {
String k = arg.substring(0, idx);
if (k.equals("d") || k.equals("distance")) {
d = Double.parseDouble(arg.substring(idx + 1));
} else {
throw new InvalidShapeException("unknown arg: " + k + " :: " + str);
}
} else {
d = Double.parseDouble(arg);
}
if (st.hasMoreTokens()) {
throw new InvalidShapeException("Extra arguments: " + st.nextToken() + " :: " + str);
}
if (d == null) {
throw new InvalidShapeException("Missing Distance: " + str);
}
//NOTE: we are assuming the units of 'd' is the same as that of the spatial context.
return ctx.makeCircle(pt, d);
}
}
return null;//caller has opportunity to try other parsing
}
if (str.indexOf(',') != -1)
return readLatCommaLonPoint(str, ctx);
StringTokenizer st = new StringTokenizer(str, " ");
double p0 = Double.parseDouble(st.nextToken());
double p1 = Double.parseDouble(st.nextToken());
if (st.hasMoreTokens()) {
double p2 = Double.parseDouble(st.nextToken());
double p3 = Double.parseDouble(st.nextToken());
if (st.hasMoreTokens())
throw new InvalidShapeException("Only 4 numbers supported (rect) but found more: " + str);
return ctx.makeRectangle(p0, p2, p1, p3);
}
return ctx.makePoint(p0, p1);
}