正如 Colin 所解释的,您没有任何类型可以签入GeoJson
对象,因此您不能使用instanceof
或其他 OOP 技术将其转换回特定的类型安全。您必须将类型设置为native=true, name="Object", namespace=GLOBAL
,然后您可以使用Js.cast
将其转换回GeoJson
类型。
如果您想要更多的 OOP,您可以使用访问者模式并将“手动类型检查”隐藏在此访问者后面,例如:
import static jsinterop.annotations.JsPackage.GLOBAL;
import javax.annotation.Nullable;
import jsinterop.annotations.JsOverlay;
import jsinterop.annotations.JsType;
@JsType(namespace = GLOBAL, name = "Object", isNative = true)
class GeoJson {
public String type;
public final @JsOverlay Type getTypeEnum() { return Type.valueOf(type); }
public final @JsOverlay void setTypeEnum(Type type) { this.type = type.name(); }
public static @JsOverlay FeatureCollection featureCollection(Feature... features) {
FeatureCollection o = new FeatureCollection();
o.setTypeEnum(Type.FeatureCollection);
o.features = features;
return o;
}
public static @JsOverlay Feature feature(Geometry geometry) { return feature(null, geometry); }
public static @JsOverlay Feature feature(@Nullable String featureId, Geometry geometry) {
Feature o = new Feature();
o.setTypeEnum(Type.Feature);
o.id = featureId;
o.geometry = geometry;
return o;
}
public static @JsOverlay Point point(double x, double y) { return point(new double[] { x, y }); }
public static @JsOverlay Point point(double[] coordinates) {
Point o = new Point();
o.setTypeEnum(Geometry.Type.Point);
o.coordinates = coordinates;
return o;
}
public static @JsOverlay Polygon polygon(double[][] coordinates) {
Polygon o = new Polygon();
o.setTypeEnum(Geometry.Type.Polygon);
o.coordinates = new double[][][] { coordinates };
return o;
}
public enum Type {Feature, FeatureCollection}
@JsType(namespace = GLOBAL, name = "Object", isNative = true)
public static final class Feature extends GeoJson {
public @Nullable String id;
public Geometry geometry;
}
@JsType(namespace = GLOBAL, name = "Object", isNative = true)
public static class FeatureCollection extends GeoJson {
public Feature[] features;
}
@JsType(namespace = GLOBAL, name = "Object", isNative = true)
public static abstract class Geometry {
public String type;
public final @JsOverlay Geometry.Type getTypeEnum() { return Geometry.Type.valueOf(type); }
public final @JsOverlay void setTypeEnum(Geometry.Type type) { this.type = type.name(); }
public final @JsOverlay <T> T accept(GeometryVisitor<T> fn) { switch (getTypeEnum()) {
case Point: return fn.point((Point) this);
case Polygon: return fn.polygon((Polygon) this);
default: throw new UnsupportedOperationException("unexpected type " + type);
} }
public static @JsOverlay @Nullable Point isPoint(@Nullable Geometry g) {
return g == null ? null : g.accept(new GeometryVisitor<Point>() {
@Override public Point point(Point g) { return g; }
@Override public Point polygon(Polygon p) { return null; }
});
}
public static @JsOverlay @Nullable Polygon isPolygon(@Nullable Geometry g) {
return g == null ? null : g.accept(new GeometryVisitor<Polygon>() {
@Override public Polygon point(Point g) { return null; }
@Override public Polygon polygon(Polygon p) { return p; }
});
}
public enum Type {Point, Polygon}
}
@JsType(namespace = GLOBAL, name = "Object", isNative = true)
public static class Point extends Geometry {
public double[] coordinates;
public final @JsOverlay double x() { return coordinates[0]; }
public final @JsOverlay double y() { return coordinates[1]; }
}
@JsType(namespace = GLOBAL, name = "Object", isNative = true)
public static final class Polygon extends Geometry {
public double[][][] coordinates;
public final @JsOverlay double[][] shell() { return coordinates[0]; }
}
public interface GeometryVisitor<T> {
T point(Point g);
T polygon(Polygon p);
}
}
基于此的示例还包括杰克逊注释,因此它也可以在服务器端。