WikibaseCornerBOp.java
package org.wikidata.query.rdf.blazegraph.constraints;
import static org.wikidata.query.rdf.blazegraph.geo.GeoUtils.pointFromIV;
import java.util.Map;
import org.openrdf.model.impl.URIImpl;
import org.wikidata.query.rdf.blazegraph.geo.GeoUtils;
import org.wikidata.query.rdf.common.WikibasePoint;
import org.wikidata.query.rdf.common.uri.GeoSparql;
import com.bigdata.bop.BOp;
import com.bigdata.bop.IBindingSet;
import com.bigdata.bop.IValueExpression;
import com.bigdata.bop.NV;
import com.bigdata.rdf.internal.IV;
import com.bigdata.rdf.internal.constraints.INeedsMaterialization;
import com.bigdata.rdf.internal.constraints.IVValueExpression;
import com.bigdata.rdf.internal.gis.CoordinateDD;
import com.bigdata.rdf.model.BigdataLiteral;
import com.bigdata.rdf.sparql.ast.GlobalAnnotations;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
/**
* Get NE or SW corners of the box, given two arbitrary diagonal corners.
*/
public class WikibaseCornerBOp extends IVValueExpression<IV> implements INeedsMaterialization {
/**
*
*/
@SuppressFBWarnings(
value = "IMC_IMMATURE_CLASS_BAD_SERIALVERSIONUID",
justification = "We need to keep serialVersionUID for blazegraph correctness sake.")
private static final long serialVersionUID = -811348263515935773L;
/**
* Corners supported by this op.
*/
public enum Corners { NE, SW }
/**
* Annotaion for specific corner.
* The operation to be applied to the operands (required).
* The value of this annotation is a {@link WikibaseCornerBOp.Corners}.
*/
private static final String OP_ANNOTATION = (WikibaseCornerBOp.class.getName() + ".op").intern();
/**
* Required shallow copy constructor.
*/
public WikibaseCornerBOp(final BOp[] args,
final Map<String, Object> anns) {
super(args, anns);
if (args.length < 2 || args[0] == null || args[1] == null)
throw new IllegalArgumentException();
}
/**
* Main ctor.
* @param left Eastern corner of the box
* @param right Wester corner of the box
* @param corner Which corner we want as the result
* @param globals The global annotations, including the lexicon namespace
*/
@SuppressWarnings("rawtypes")
public WikibaseCornerBOp(final IValueExpression<? extends IV> left,
final IValueExpression<? extends IV> right,
final Corners corner,
final GlobalAnnotations globals) {
this(new BOp[]{left, right},
anns(globals, new NV(OP_ANNOTATION, corner)));
}
/**
* Constructor required for {@link com.bigdata.bop.BOpUtility#deepCopy(BOp)})}.
*/
public WikibaseCornerBOp(final WikibaseCornerBOp op) {
super(op);
}
/**
* Get which corner we're needing for this op.
* @return The corner for this specific op.
*/
private Corners corner() {
return (Corners) getRequiredProperty(OP_ANNOTATION);
}
/**
* Get coordinate from WikibasePoint value.
*
* @return Coordinate
*/
protected CoordinateDD getCoordinateFromWP(WikibasePoint point) {
return new CoordinateDD(Double.parseDouble(point.getLatitude()),
Double.parseDouble(point.getLongitude()));
}
@Override
public IV get(IBindingSet bindingSet) {
final IV east = getAndCheckLiteral(0, bindingSet);
final IV west = getAndCheckLiteral(1, bindingSet);
final GeoUtils.Box box = new GeoUtils.Box(pointFromIV(east), pointFromIV(west));
WikibasePoint wp;
if (corner() == Corners.NE) {
if (!box.switched()) {
return east;
}
wp = box.northEast();
} else {
if (!box.switched()) {
return west;
}
wp = box.southWest();
}
final BigdataLiteral newpoint = getValueFactory().createLiteral(
wp.toString(), new URIImpl(GeoSparql.WKT_LITERAL));
return super.asIV(newpoint, bindingSet);
}
@Override
public Requirement getRequirement() {
return Requirement.ALWAYS;
}
}