afs commented on code in PR #3027:
URL: https://github.com/apache/jena/pull/3027#discussion_r2063785721
##########
jena-arq/src/main/java/org/apache/jena/sparql/util/Context.java:
##########
@@ -387,6 +389,11 @@ public void clear() {
context.clear();
}
+ /** Atomic compute. */
+ public <V> Object compute(Symbol key, BiFunction<Symbol, Object, V>
remappingFunction) {
Review Comment:
This does mot seem to be used anywhere.
##########
jena-geosparql/src/main/java/org/apache/jena/geosparql/spatial/SpatialIndexFindUtils.java:
##########
@@ -0,0 +1,189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jena.geosparql.spatial;
+
+import java.lang.invoke.MethodHandles;
+import java.util.Iterator;
+import java.util.List;
Review Comment:
Not used?
##########
jena-geosparql/src/main/java/org/apache/jena/geosparql/spatial/index/v2/STRtreePerGraphSerializer.java:
##########
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jena.geosparql.spatial.index.v2;
+
+import java.util.Map;
+
+import org.apache.jena.graph.Node;
+import org.locationtech.jts.index.strtree.STRtree;
+
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.Serializer;
+import com.esotericsoftware.kryo.io.Input;
+import com.esotericsoftware.kryo.io.Output;
+
+public class STRtreePerGraphSerializer
+ extends Serializer<STRtreePerGraph>
+{
+ @Override
+ public void write(Kryo kryo, Output output, STRtreePerGraph index) {
+ kryo.writeClassAndObject(output, index.getInternalTreeMap());
+ output.writeBoolean(index.isBuilt());
+ }
+
+ @Override
+ public STRtreePerGraph read(Kryo kryo, Input input, Class<STRtreePerGraph>
type) {
+ Map<Node, STRtree> treeMap = (Map<Node,
STRtree>)kryo.readClassAndObject(input);
Review Comment:
Add `@SuppressWarnings("unchecked")`
##########
jena-geosparql/src/main/java/org/apache/jena/geosparql/spatial/index/v1/SpatialIndexV1.java:
##########
@@ -0,0 +1,577 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jena.geosparql.spatial.index.v1;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.invoke.MethodHandles;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.jena.atlas.RuntimeIOException;
+import org.apache.jena.atlas.io.IOX;
+import org.apache.jena.geosparql.configuration.GeoSPARQLOperations;
+import org.apache.jena.geosparql.implementation.GeometryWrapper;
+import org.apache.jena.geosparql.implementation.SRSInfo;
+import org.apache.jena.geosparql.implementation.registry.SRSRegistry;
+import org.apache.jena.geosparql.implementation.vocabulary.Geo;
+import org.apache.jena.geosparql.implementation.vocabulary.SRS_URI;
+import org.apache.jena.geosparql.implementation.vocabulary.SpatialExtension;
+import org.apache.jena.geosparql.spatial.ConvertLatLon;
+import org.apache.jena.geosparql.spatial.SpatialIndex;
+import org.apache.jena.geosparql.spatial.SpatialIndexException;
+import org.apache.jena.geosparql.spatial.SpatialIndexItem;
+import org.apache.jena.geosparql.spatial.SpatialIndexStorage;
+import org.apache.jena.geosparql.spatial.index.v2.SpatialIndexUtils;
+import org.apache.jena.query.Dataset;
+import org.apache.jena.query.DatasetFactory;
+import org.apache.jena.query.ReadWrite;
+import org.apache.jena.rdf.model.Literal;
+import org.apache.jena.rdf.model.Model;
+import org.apache.jena.rdf.model.NodeIterator;
+import org.apache.jena.rdf.model.RDFNode;
+import org.apache.jena.rdf.model.ResIterator;
+import org.apache.jena.rdf.model.Resource;
+import org.apache.jena.rdf.model.Statement;
+import org.apache.jena.rdf.model.StmtIterator;
+import org.apache.jena.sparql.engine.ExecutionContext;
+import org.apache.jena.sparql.util.Context;
+import org.apache.jena.sparql.util.ModelUtils;
+import org.apache.jena.util.iterator.ExtendedIterator;
+import org.locationtech.jts.geom.Envelope;
+import org.locationtech.jts.index.strtree.STRtree;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.referencing.operation.TransformException;
+import org.opengis.util.FactoryException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * SpatialIndex for testing bounding box collisions between geometries within a
+ * Dataset.<br>
+ * Queries must be performed using the same SRS URI as the SpatialIndex.<br>
+ * The SpatialIndex is added to the Dataset Context when it is built.<br>
+ * QueryRewriteIndex is also stored in the SpatialIndex as its content is
+ * Dataset specific.
+ */
+@Deprecated /** Superseded by {@link SpatialIndex} and {@link
SpatialIndexPerGraph}. */
Review Comment:
Should this be `@Deprecated(forRemoval = true)`?
##########
jena-geosparql/src/main/java/org/apache/jena/geosparql/spatial/index/v1/SpatialIndexAdapterV1.java:
##########
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jena.geosparql.spatial.index.v1;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.apache.jena.geosparql.implementation.SRSInfo;
+import org.apache.jena.geosparql.spatial.SpatialIndex;
+import org.apache.jena.graph.Node;
+import org.apache.jena.rdf.model.RDFNode;
+import org.apache.jena.rdf.model.Resource;
+import org.locationtech.jts.geom.Envelope;
+
+/** Adapter class for spatial index v1. */
+public class SpatialIndexAdapterV1
Review Comment:
Several deprecation warnings.
Maybe add `@SuppressWarnings("deprecation")` to the class.
##########
jena-geosparql/src/test/java/org/apache/jena/geosparql/spatial/SpatialIndexTestData.java:
##########
@@ -60,21 +71,28 @@ public class SpatialIndexTestData {
public static final SRSInfo WGS_84_SRS_INFO = new
SRSInfo(SRS_URI.WGS84_CRS);
public static final SRSInfo OSGB_SRS_INFO = new
SRSInfo(SRS_URI.OSGB36_CRS);
- private static SpatialIndex TEST_SPATIAL_INDEX = null;
+ private static SpatialIndexPerGraph TEST_SPATIAL_INDEX = null;
private static Dataset TEST_DATASET = null;
- public static final SpatialIndex createTestIndex() {
+ public static final List<SpatialIndexItem> getTestItems() {
+ List<SpatialIndexItem> items = List.of(
+ SpatialIndexItem.of(LONDON_GEOMETRY_WRAPPER.getEnvelope(),
LONDON_FEATURE),
Review Comment:
5 deprecated functions here. Add `.asNode()` to second argument.
##########
jena-geosparql/src/main/java/org/apache/jena/geosparql/kryo/NodeSerializer.java:
##########
@@ -0,0 +1,346 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jena.geosparql.kryo;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.stream.Collectors;
+
+import org.apache.jena.datatypes.RDFDatatype;
+import org.apache.jena.datatypes.TypeMapper;
+import org.apache.jena.graph.Graph;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.graph.Node_ANY;
+import org.apache.jena.graph.Node_Blank;
+import org.apache.jena.graph.Node_Graph;
+import org.apache.jena.graph.Node_Literal;
+import org.apache.jena.graph.Node_Triple;
+import org.apache.jena.graph.Node_URI;
+import org.apache.jena.graph.Node_Variable;
+import org.apache.jena.graph.TextDirection;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.sparql.core.Quad;
+import org.apache.jena.sparql.core.Var;
+import org.apache.jena.vocabulary.OWL;
+import org.apache.jena.vocabulary.RDF;
+import org.apache.jena.vocabulary.RDFS;
+import org.apache.jena.vocabulary.XSD;
+
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.Serializer;
+import com.esotericsoftware.kryo.io.Input;
+import com.esotericsoftware.kryo.io.Output;
+
+/**
+ * An RDF1.2 node serializer for kryo.
+ */
+public class NodeSerializer
+ extends Serializer<Node>
+{
+ public static void register(Kryo kryo) {
+ register(kryo, new NodeSerializer());
+ }
+
+ /**
+ * Registers serializers for all Jena Node types - except for Node_Ext and
any subclasses.
+ *
+ * For Node_Triple and Node_Graph to function, additional serializers for
+ * Triple and Graph need to be registered.
+ */
+ public static void register(Kryo kryo, Serializer<Node> nodeSerializer) {
+ // Concrete nodes
+ kryo.register(Node.class, nodeSerializer);
+ kryo.register(Node_Blank.class, nodeSerializer);
+ kryo.register(Node_URI.class, nodeSerializer);
+ kryo.register(Node_Literal.class, nodeSerializer);
+ kryo.register(Node_Triple.class, nodeSerializer);
+
+ // Variable nodes
+ kryo.register(Node_Variable.class, nodeSerializer);
+ kryo.register(Var.class, nodeSerializer);
+ kryo.register(Node_ANY.class, nodeSerializer);
+
+ // Extensions
+ kryo.register(Node_Graph.class, nodeSerializer);
+ }
+
+ protected static final byte TYPE_MASK = (byte)0xf0; // 1111 0000
+ protected static final byte TYPE_IRI = 0x10; // 0001 0000
+ protected static final byte TYPE_BNODE = 0x20; // 0010 0000
+ protected static final byte TYPE_LITERAL = 0x30; // 0011 0000
+ protected static final byte TYPE_TRIPLE = 0x40; // 0100 0000
+ protected static final byte TYPE_GRAPH = 0x50; // 0101 0000 -
Delegates back to kryo
+
+ protected static final byte TYPE_VAR = (byte)0x80; // 1000 0000 -
NoteFactory.createVariable
+ protected static final byte TYPE_SVAR = (byte)0x90; // 1001 0000 -
Var.alloc
+ protected static final byte TYPE_ANY = (byte)0xa0; // 1010 0000
+ protected static final byte TYPE_EXT = (byte)0xb0; // 1011 0000 -
Delegates back to kryo
+
+ protected static final byte LITERAL_MASK = 0x03; // 0000 0011
+ protected static final byte LITERAL_STRING = 0x00; // 0000 0000
+ protected static final byte LITERAL_LANG = 0x01; // 0000 0001
+ protected static final byte LITERAL_DTYPE = 0x02; // 0000 0010
+
+ // Iff (TYPE_LITERAL and LITERAL_LANG) the following applies:
+ protected static final byte LITERAL_LANG_MASK = 0x0c; // 0000 1100
+ protected static final byte LITERAL_LANG_LTR = 0x04; // 0000 0100
+ protected static final byte LITERAL_LANG_RTL = 0x08; // 0000 1000
+
+ // Iff (TYPE_IRI) or (TYPE_LITERAL & LITERAL_DYTE): Whether the value
field is abbreviated.
+ protected static final byte ABBREV_IRI = 0x08; // 0000 1000
+
+ private static Map<String, String> globalPrefixToIri = new HashMap<>();
+
+ private Map<String, String> prefixToIri = new HashMap<>();
+ private Map<String, String> iriToPrefix = new HashMap<>();
+
+ static {
+ globalPrefixToIri.put("a", RDF.type.getURI());
+ globalPrefixToIri.put("d", Quad.defaultGraphIRI.getURI());
+ globalPrefixToIri.put("g", Quad.defaultGraphNodeGenerated.getURI());
+ globalPrefixToIri.put("x", XSD.NS);
+ globalPrefixToIri.put("r", RDF.uri);
+ globalPrefixToIri.put("s", RDFS.uri);
+ globalPrefixToIri.put("o", OWL.NS);
+ }
+
+ /**
+ * Takes a guess for the namespace URI string to use in abbreviation.
+ * Finds the part of the IRI string before the last '#', '/', ':' or '.'.
+ *
+ * @param iriString String string
+ * @return String or null
+ */
+ // XXX Should use a trie instead.
+ private static String getCandidateNamespaceIri(String iriString) {
+ int n = iriString.length();
+ int i;
+ loop: for (i = n - 1; i >= 0; --i) {
+ char c = iriString.charAt(i);
+ switch(c) {
+ case '#':
+ case '/':
+ case ':':
+ case '.':
+ break loop;
+ default:
+ // continue
+ }
+ }
+ String result = i >= 0 ? iriString.substring(0, i + 1) : null;
+ return result;
+ }
+
+ private static String encode(Map<String, String> iriToPrefix, String iri) {
+ String result = iriToPrefix.get(iri);
+ if (result == null) {
+ String nsIri = getCandidateNamespaceIri(iri);
+ if (nsIri != null) {
+ String prefix = iriToPrefix.get(nsIri);
+ if (prefix != null) {
+ result = prefix + ":" + iri.substring(nsIri.length());
+ }
+ }
+ }
+ return result;
+ }
+
+ private static String decode(Map<String, String> prefixToIri, String
curie) {
+ String result;
+ int idx = curie.indexOf(':');
+ if (idx < 0) {
+ result = prefixToIri.get(curie);
+ } else {
+ String prefix = curie.substring(0, idx);
+ String iri = prefixToIri.get(prefix);
+ result = iri + curie.substring(idx + 1);
+ }
+ return result;
+ }
+
+ protected TypeMapper typeMapper;
+
+ public NodeSerializer() {
+ this(TypeMapper.getInstance());
+ }
+
+ public NodeSerializer(TypeMapper typeMapper) {
+ this(typeMapper, globalPrefixToIri);
+ }
+
+ public NodeSerializer(TypeMapper typeMapper, Map<String, String>
prefixToIri) {
+ super();
+ this.typeMapper = typeMapper;
+ this.prefixToIri = new HashMap<>(prefixToIri);
+
+ this.iriToPrefix = prefixToIri.entrySet().stream()
+ .collect(Collectors.toMap(Entry::getValue, Entry::getKey));
+ }
+
+ @Override
+ public void write(Kryo kryo, Output output, Node node) {
+ if (node.isURI()) {
+ String uri = node.getURI();
+ String curie = encode(iriToPrefix, uri);
+ if (curie != null) {
+ output.writeByte(TYPE_IRI | ABBREV_IRI);
+ output.writeString(curie);
+ } else {
+ output.writeByte(TYPE_IRI);
+ output.writeString(uri);
+ }
+ } else if (node.isLiteral()) {
+ String lex = node.getLiteralLexicalForm();
+ String lang = node.getLiteralLanguage();
+ String dt = node.getLiteralDatatypeURI();
+ TextDirection dir = node.getLiteralBaseDirection();
+
+ if (lang != null && !lang.isEmpty()) {
+ byte langDirBits = dir == null ? (byte)0 : switch(dir) {
+ case LTR -> LITERAL_LANG_LTR;
+ case RTL -> LITERAL_LANG_RTL;
+ };
+ output.writeByte(TYPE_LITERAL | LITERAL_LANG | langDirBits);
+ output.writeString(lex);
+ output.writeString(lang);
+ } else if (dt != null && !dt.isEmpty() &&
!dt.equals(XSD.xstring.getURI())) {
+ String dtCurie = encode(iriToPrefix, dt);
+ if (dtCurie != null) {
+ output.writeByte(TYPE_LITERAL | LITERAL_DTYPE |
ABBREV_IRI);
+ output.writeString(lex);
+ output.writeString(dtCurie);
+ } else {
+ output.writeByte(TYPE_LITERAL | LITERAL_DTYPE);
+ output.writeString(lex);
+ output.writeString(dt);
+ }
+ } else {
+ output.writeByte(TYPE_LITERAL);
+ output.writeString(lex);
+ }
+ } else if (node.isBlank()) {
+ output.writeByte(TYPE_BNODE);
+ output.writeString(node.getBlankNodeLabel());
+ } else if (Node.ANY.equals(node)) {
+ output.writeByte(TYPE_ANY);
+ } else if (node.isVariable()) {
+ if (node instanceof Var) {
+ output.writeByte(TYPE_SVAR);
+ } else {
+ output.writeByte(TYPE_VAR);
+ }
+ output.writeString(node.getName());
+ } else if (node.isTripleTerm()) {
+ output.writeByte(TYPE_TRIPLE);
+ kryo.writeObject(output, node.getTriple());
+ } else if (node.isNodeGraph()) {
+ output.writeByte(TYPE_GRAPH);
+ kryo.writeObject(output, node.getGraph());
+ } else if (node.isExt()) {
+ output.writeByte(TYPE_EXT);
+ kryo.writeClassAndObject(output, node);
+ } else {
+ throw new RuntimeException("Unknown node type: " + node);
+ }
+ }
+
+ @Override
+ public Node read(Kryo kryo, Input input, Class<Node> cls) {
+ Node result;
+ String v1, v2;
+ Triple t;
+
+ byte type = input.readByte();
+
+ int typeVal = type & TYPE_MASK;
+ switch (typeVal) {
+ case TYPE_IRI:
+ v1 = input.readString();
+ if ((type & ABBREV_IRI) != 0) {
+ v1 = decode(prefixToIri, v1);
+ }
+ result = NodeFactory.createURI(v1);
+ break;
+ case TYPE_LITERAL:
+ int subTypeVal = type & LITERAL_MASK;
+ switch (subTypeVal) {
+ case LITERAL_STRING:
+ v1 = input.readString();
+ result = NodeFactory.createLiteralString(v1);
+ break;
+ case LITERAL_LANG:
+ int langDirBits = type & LITERAL_LANG_MASK;
+
+ TextDirection textDir = switch(langDirBits) {
+ case LITERAL_LANG_LTR -> TextDirection.LTR;
+ case LITERAL_LANG_RTL -> TextDirection.RTL;
+ default -> Node.noTextDirection;
+ };
+
+ v1 = input.readString();
+ v2 = input.readString();
+ result = NodeFactory.createLiteralDirLang(v1, v2,
textDir);
+ break;
+ case LITERAL_DTYPE:
+ v1 = input.readString();
+ v2 = input.readString();
+ if ((type & ABBREV_IRI) != 0) {
+ v2 = decode(prefixToIri, v2);
+ }
+ RDFDatatype dtype = typeMapper.getSafeTypeByName(v2);
+ result = NodeFactory.createLiteralDT(v1, dtype);
+ break;
+ default:
+ throw new RuntimeException("Unknown literal sub-type:
" + subTypeVal);
+ }
+ break;
+ case TYPE_BNODE:
+ v1 = input.readString();
+ result = NodeFactory.createBlankNode(v1);
+ break;
+ case TYPE_TRIPLE:
+ t = kryo.readObject(input, Triple.class);
+ result = NodeFactory.createTripleNode(t);
Review Comment:
```suggestion
result = NodeFactory.createTripleTerm(t);
```
`createTripleNode` is deprecated.
##########
jena-geosparql/src/main/java/org/apache/jena/geosparql/spatial/SpatialIndexFindUtils.java:
##########
@@ -0,0 +1,189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jena.geosparql.spatial;
+
+import java.lang.invoke.MethodHandles;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.jena.atlas.iterator.Iter;
+import org.apache.jena.atlas.iterator.IteratorCloseable;
+import org.apache.jena.geosparql.implementation.GeometryWrapper;
+import org.apache.jena.geosparql.implementation.vocabulary.Geo;
+import org.apache.jena.geosparql.implementation.vocabulary.SpatialExtension;
+import org.apache.jena.graph.Graph;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.sparql.core.DatasetGraph;
+import org.apache.jena.system.G;
+import org.locationtech.jts.geom.Envelope;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.referencing.operation.TransformException;
+import org.opengis.util.FactoryException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SpatialIndexFindUtils {
+ private static final Logger LOGGER =
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+ /**
+ * Find Spatial Index Items from all graphs in Dataset.<br>
+ *
+ * @param datasetGraph
+ * @param srsURI
+ * @return SpatialIndexItems found.
+ * @throws SpatialIndexException
Review Comment:
This causes a javadoc warning because there isn't a `throws` for
`SpatialIndexException` (3 occurrences of same situation).
##########
jena-geosparql/src/main/java/org/apache/jena/geosparql/spatial/task/AbortableThread.java:
##########
@@ -0,0 +1,200 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.geosparql.spatial.task;
+
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.BiConsumer;
+
+import org.apache.jena.geosparql.spatial.task.TaskControl.Registration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Thread base class that provides {@link #cancel()} and {@link
#requestingCancel} methods
+ * that can run a custom action (in addition to setting the interrupted flag)
+ * as well as a {@link #doAfterRun()} method for cleaning up after execution
+ * (only called if there is a prior call to run).
+ */
+public abstract class AbortableThread<T>
+ extends Thread
+{
+ private static final Logger logger =
LoggerFactory.getLogger(AbortableThread.class);
+
+ private final AtomicBoolean requestingCancel;
+ private volatile boolean cancelOnce = false;
+ private Object cancelLock = new Object();
+
+ protected List<BiConsumer<? super T, Throwable>> completionHandlers = new
ArrayList<>();
+
+ private boolean isComplete = false;
+ private T value = null;
+ private Throwable throwable;
+
+ private Instant startTime;
+ private String statusMessage;
+
+ /**
+ * Time of the first abort request; null if there is none.
+ * Cancel time will not be set if cancel is called after a task's
completion.
+ */
+ private Instant cancelTime;
+ private Instant endTime;
+
+ // XXX Add native support for CompletableFuture?
+
+ public AbortableThread() {
+ this(new AtomicBoolean());
+ }
+
+ public AbortableThread(AtomicBoolean requestingCancel) {
+ super();
+ this.requestingCancel = Objects.requireNonNull(requestingCancel);
+ }
+
+ public final boolean isComplete() {
+ return isComplete;
+ }
+
+ public T getValue() {
+ return value;
+ }
+
+ public Throwable getThrowable() {
+ return throwable;
+ }
+
+ public Instant getStartTime() {
+ return startTime;
+ }
+
+ public Instant getEndTime() {
+ return endTime;
+ }
+
+ public Instant getCancelTime() {
+ return cancelTime;
+ }
+
+ protected void setStatusMessage(String statusMessage) {
+ this.statusMessage = statusMessage;
+ }
+
+ public String getStatusMessage() {
+ return statusMessage;
+ }
+
+ public final void run() {
Review Comment:
```suggestion
@Override
public final void run() {
```
##########
jena-geosparql/src/main/java/org/apache/jena/geosparql/spatial/SpatialIndex.java:
##########
@@ -17,530 +17,45 @@
*/
package org.apache.jena.geosparql.spatial;
-import java.io.*;
-import java.lang.invoke.MethodHandles;
-import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.*;
+import java.util.Collection;
-import org.apache.jena.atlas.RuntimeIOException;
-import org.apache.jena.atlas.io.IOX;
-import org.apache.jena.geosparql.configuration.GeoSPARQLOperations;
-import org.apache.jena.geosparql.implementation.GeometryWrapper;
import org.apache.jena.geosparql.implementation.SRSInfo;
-import org.apache.jena.geosparql.implementation.registry.SRSRegistry;
-import org.apache.jena.geosparql.implementation.vocabulary.Geo;
-import org.apache.jena.geosparql.implementation.vocabulary.SRS_URI;
-import org.apache.jena.geosparql.implementation.vocabulary.SpatialExtension;
-import org.apache.jena.query.Dataset;
-import org.apache.jena.query.DatasetFactory;
-import org.apache.jena.query.ReadWrite;
-import org.apache.jena.rdf.model.*;
-import org.apache.jena.sparql.engine.ExecutionContext;
-import org.apache.jena.sparql.util.Context;
-import org.apache.jena.sparql.util.Symbol;
-import org.apache.jena.util.iterator.ExtendedIterator;
+import org.apache.jena.graph.Node;
+import org.apache.jena.sparql.core.Quad;
import org.locationtech.jts.geom.Envelope;
-import org.locationtech.jts.index.strtree.STRtree;
-import org.opengis.geometry.MismatchedDimensionException;
-import org.opengis.referencing.operation.TransformException;
-import org.opengis.util.FactoryException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-/**
- * SpatialIndex for testing bounding box collisions between geometries within a
- * Dataset.<br>
- * Queries must be performed using the same SRS URI as the SpatialIndex.<br>
- * The SpatialIndex is added to the Dataset Context when it is built.<br>
- * QueryRewriteIndex is also stored in the SpatialIndex as its content is
- * Dataset specific.
- *
- */
-public class SpatialIndex {
-
- private static final Logger LOGGER =
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
- public static final Symbol SPATIAL_INDEX_SYMBOL =
Symbol.create("http://jena.apache.org/spatial#index");
-
- private transient final SRSInfo srsInfo;
- private boolean isBuilt;
- private final STRtree strTree;
- private static final int MINIMUM_CAPACITY = 2;
-
- private SpatialIndex() {
- this.strTree = new STRtree(MINIMUM_CAPACITY);
- this.isBuilt = true;
- this.strTree.build();
- this.srsInfo = SRSRegistry.getSRSInfo(SRS_URI.DEFAULT_WKT_CRS84);
- }
-
- /**
- * Unbuilt Spatial Index with provided capacity.
- *
- * @param capacity
- * @param srsURI
- */
- public SpatialIndex(int capacity, String srsURI) {
- int indexCapacity = capacity < MINIMUM_CAPACITY ? MINIMUM_CAPACITY :
capacity;
- this.strTree = new STRtree(indexCapacity);
- this.isBuilt = false;
- this.srsInfo = SRSRegistry.getSRSInfo(srsURI);
- }
-
- /**
- * Built Spatial Index with provided capacity.
- *
- * @param spatialIndexItems
- * @param srsURI
- * @throws SpatialIndexException
- */
- public SpatialIndex(Collection<SpatialIndexItem> spatialIndexItems, String
srsURI) throws SpatialIndexException {
- int indexCapacity = spatialIndexItems.size() < MINIMUM_CAPACITY ?
MINIMUM_CAPACITY : spatialIndexItems.size();
- this.strTree = new STRtree(indexCapacity);
- insertItems(spatialIndexItems);
- this.strTree.build();
- this.isBuilt = true;
- this.srsInfo = SRSRegistry.getSRSInfo(srsURI);
- }
+public interface SpatialIndex {
/**
*
* @return Information about the SRS used by the SpatialIndex.
*/
- public SRSInfo getSrsInfo() {
- return srsInfo;
- }
+ SRSInfo getSrsInfo();
/**
*
* @return True if the SpatialIndex is empty.
*/
- public boolean isEmpty() {
- return strTree.isEmpty();
- }
-
- /**
- *
- * @return True if the SpatialIndex has been built.
- */
- public boolean isBuilt() {
- return isBuilt;
- }
-
- /**
- * Build the Spatial Index. No more items can be added.
- */
- public void build() {
- if (!isBuilt) {
- strTree.build();
- isBuilt = true;
- }
- }
+ boolean isEmpty();
/**
- * Items to add to an unbuilt Spatial Index.
- *
- * @param indexItems
- * @throws SpatialIndexException
+ * Returns the number of items in the index.
*/
- public final void insertItems(Collection<SpatialIndexItem> indexItems)
throws SpatialIndexException {
-
- for (SpatialIndexItem indexItem : indexItems) {
- insertItem(indexItem.getEnvelope(), indexItem.getItem());
- }
- }
+ long getSize();
/**
- * Item to add to an unbuilt Spatial Index.
+ * Query the index for all matching data in the given graph.
*
- * @param envelope
- * @param item
- * @throws SpatialIndexException
- */
- public final void insertItem(Envelope envelope, Resource item) throws
SpatialIndexException {
- if (!isBuilt) {
- strTree.insert(envelope, item);
- } else {
- throw new SpatialIndexException("SpatialIndex has been built and
cannot have additional items.");
- }
- }
-
- @SuppressWarnings("unchecked")
- public HashSet<Resource> query(Envelope searchEnvelope) {
- if (!strTree.isEmpty()) {
- return new HashSet<>(strTree.query(searchEnvelope));
- } else {
- return new HashSet<>();
- }
- }
-
- @Override
- public String toString() {
- return "SpatialIndex{" + "srsInfo=" + srsInfo + ", isBuilt=" + isBuilt
+ ", strTree=" + strTree + '}';
- }
-
- /**
- * Retrieve the SpatialIndex from the Context.
- *
- * @param execCxt
- * @return SpatialIndex contained in the Context.
- * @throws SpatialIndexException
- */
- public static final SpatialIndex retrieve(ExecutionContext execCxt) throws
SpatialIndexException {
-
- Context context = execCxt.getContext();
- SpatialIndex spatialIndex = (SpatialIndex)
context.get(SPATIAL_INDEX_SYMBOL, null);
-
- if (spatialIndex == null) {
- throw new SpatialIndexException("Dataset Context does not contain
SpatialIndex.");
- }
-
- return spatialIndex;
- }
-
- /**
- *
- * @param execCxt
- * @return True if a SpatialIndex is defined in the ExecutionContext.
- */
- public static final boolean isDefined(ExecutionContext execCxt) {
- Context context = execCxt.getContext();
- return context.isDefined(SPATIAL_INDEX_SYMBOL);
- }
-
- /**
- * Set the SpatialIndex into the Context of the Dataset for later retrieval
- * and use in spatial functions.
- *
- * @param dataset
- * @param spatialIndex
- */
- public static final void setSpatialIndex(Dataset dataset, SpatialIndex
spatialIndex) {
- Context context = dataset.getContext();
- context.set(SPATIAL_INDEX_SYMBOL, spatialIndex);
- }
-
- /**
- * Build Spatial Index from all graphs in Dataset.<br>
- * Dataset contains SpatialIndex in Context.<br>
- * Spatial Index written to file.
- *
- * @param dataset
- * @param srsURI
- * @param spatialIndexFile
- * @return SpatialIndex constructed.
- * @throws SpatialIndexException
- */
- public static SpatialIndex buildSpatialIndex(Dataset dataset, String
srsURI, File spatialIndexFile) throws SpatialIndexException {
-
- SpatialIndex spatialIndex = load(spatialIndexFile);
-
- if (spatialIndex.isEmpty()) {
- Collection<SpatialIndexItem> spatialIndexItems =
findSpatialIndexItems(dataset, srsURI);
- save(spatialIndexFile, spatialIndexItems, srsURI);
- spatialIndex = new SpatialIndex(spatialIndexItems, srsURI);
- spatialIndex.build();
- }
-
- setSpatialIndex(dataset, spatialIndex);
- return spatialIndex;
- }
-
- /**
- * Build Spatial Index from all graphs in Dataset.<br>
- * Dataset contains SpatialIndex in Context.<br>
- * SRS URI based on most frequent found in Dataset.<br>
- * Spatial Index written to file.
- *
- * @param dataset
- * @param spatialIndexFile
- * @return SpatialIndex constructed.
- * @throws SpatialIndexException
- */
- public static SpatialIndex buildSpatialIndex(Dataset dataset, File
spatialIndexFile) throws SpatialIndexException {
- String srsURI = GeoSPARQLOperations.findModeSRS(dataset);
- SpatialIndex spatialIndex = buildSpatialIndex(dataset, srsURI,
spatialIndexFile);
- return spatialIndex;
- }
-
- /**
- * Build Spatial Index from all graphs in Dataset.<br>
- * Dataset contains SpatialIndex in Context.
- *
- * @param dataset
- * @param srsURI
- * @return SpatialIndex constructed.
- * @throws SpatialIndexException
- */
- public static SpatialIndex buildSpatialIndex(Dataset dataset, String
srsURI) throws SpatialIndexException {
- LOGGER.info("Building Spatial Index - Started");
-
- Collection<SpatialIndexItem> items = findSpatialIndexItems(dataset,
srsURI);
- SpatialIndex spatialIndex = new SpatialIndex(items, srsURI);
- spatialIndex.build();
- setSpatialIndex(dataset, spatialIndex);
- LOGGER.info("Building Spatial Index - Completed");
- return spatialIndex;
- }
-
- /**
- * Find Spatial Index Items from all graphs in Dataset.<br>
- *
- * @param dataset
- * @param srsURI
- * @return SpatialIndexItems found.
- * @throws SpatialIndexException
- */
- public static Collection<SpatialIndexItem> findSpatialIndexItems(Dataset
dataset, String srsURI) throws SpatialIndexException {
- //Default Model
- dataset.begin(ReadWrite.READ);
- Model defaultModel = dataset.getDefaultModel();
- Collection<SpatialIndexItem> items =
getSpatialIndexItems(defaultModel, srsURI);
-
- //Named Models
- Iterator<String> graphNames = dataset.listNames();
- while (graphNames.hasNext()) {
- String graphName = graphNames.next();
- Model namedModel = dataset.getNamedModel(graphName);
- Collection<SpatialIndexItem> graphItems =
getSpatialIndexItems(namedModel, srsURI);
- items.addAll(graphItems);
- }
-
- dataset.end();
-
- return items;
- }
-
- /**
- * Build Spatial Index from all graphs in Dataset.<br>
- * Dataset contains SpatialIndex in Context.<br>
- * SRS URI based on most frequent found in Dataset.
- *
- * @param dataset
- * @return SpatialIndex constructed.
- * @throws SpatialIndexException
- */
- public static SpatialIndex buildSpatialIndex(Dataset dataset) throws
SpatialIndexException {
- String srsURI = GeoSPARQLOperations.findModeSRS(dataset);
- SpatialIndex spatialIndex = buildSpatialIndex(dataset, srsURI);
- return spatialIndex;
- }
-
- /**
- * Wrap Model in a Dataset and build SpatialIndex.
- *
- * @param model
- * @param srsURI
- * @return Dataset with default Model and SpatialIndex in Context.
- * @throws SpatialIndexException
- */
- public static final Dataset wrapModel(Model model, String srsURI) throws
SpatialIndexException {
-
- Dataset dataset = DatasetFactory.createTxnMem();
- dataset.setDefaultModel(model);
- buildSpatialIndex(dataset, srsURI);
-
- return dataset;
- }
-
- /**
- * Wrap Model in a Dataset and build SpatialIndex.
- *
- * @param model
- * @return Dataset with default Model and SpatialIndex in Context.
- * @throws SpatialIndexException
- */
- public static final Dataset wrapModel(Model model) throws
SpatialIndexException {
- Dataset dataset = DatasetFactory.createTxnMem();
- dataset.setDefaultModel(model);
- String srsURI = GeoSPARQLOperations.findModeSRS(dataset);
- buildSpatialIndex(dataset, srsURI);
-
- return dataset;
- }
-
- /**
- * Find items from the Model transformed to the SRS URI.
- *
- * @param model
- * @param srsURI
- * @return Items found in the Model in the SRS URI.
- * @throws SpatialIndexException
- */
- public static final Collection<SpatialIndexItem>
getSpatialIndexItems(Model model, String srsURI) throws SpatialIndexException {
-
- List<SpatialIndexItem> items = new ArrayList<>();
-
- //Only add one set of statements as a converted dataset will duplicate
the same info.
- if (model.contains(null, Geo.HAS_GEOMETRY_PROP, (Resource) null)) {
- LOGGER.info("Feature-hasGeometry-Geometry statements found.");
- if (model.contains(null, SpatialExtension.GEO_LAT_PROP, (Literal)
null)) {
- LOGGER.warn("Lat/Lon Geo predicates also found but will not be
added to index.");
- }
- Collection<SpatialIndexItem> geometryLiteralItems =
getGeometryLiteralIndexItems(model, srsURI);
- items.addAll(geometryLiteralItems);
- } else if (model.contains(null, SpatialExtension.GEO_LAT_PROP,
(Literal) null)) {
- LOGGER.info("Geo predicate statements found.");
- Collection<SpatialIndexItem> geoPredicateItems =
getGeoPredicateIndexItems(model, srsURI);
- items.addAll(geoPredicateItems);
- }
-
- return items;
- }
-
- /**
- *
- * @param model
- * @param srsURI
- * @return GeometryLiteral items prepared for adding to SpatialIndex.
- * @throws SpatialIndexException
- */
- private static Collection<SpatialIndexItem>
getGeometryLiteralIndexItems(Model model, String srsURI) throws
SpatialIndexException {
- List<SpatialIndexItem> items = new ArrayList<>();
- StmtIterator stmtIt = model.listStatements(null,
Geo.HAS_GEOMETRY_PROP, (Resource) null);
- while (stmtIt.hasNext()) {
- Statement stmt = stmtIt.nextStatement();
-
- Resource feature = stmt.getSubject();
- Resource geometry = stmt.getResource();
-
- ExtendedIterator<RDFNode> nodeIter =
model.listObjectsOfProperty(geometry, Geo.HAS_SERIALIZATION_PROP);
- if (!nodeIter.hasNext()) {
- NodeIterator wktNodeIter =
model.listObjectsOfProperty(geometry, Geo.AS_WKT_PROP);
- NodeIterator gmlNodeIter =
model.listObjectsOfProperty(geometry, Geo.AS_GML_PROP);
- nodeIter = wktNodeIter.andThen(gmlNodeIter);
- }
-
- while (nodeIter.hasNext()) {
- Literal geometryLiteral = nodeIter.next().asLiteral();
- GeometryWrapper geometryWrapper =
GeometryWrapper.extract(geometryLiteral);
-
- try {
- //Ensure all entries in the target SRS URI.
- GeometryWrapper transformedGeometryWrapper =
geometryWrapper.convertSRS(srsURI);
-
- Envelope envelope =
transformedGeometryWrapper.getEnvelope();
- SpatialIndexItem item = new SpatialIndexItem(envelope,
feature);
- items.add(item);
- } catch (FactoryException | MismatchedDimensionException |
TransformException ex) {
- throw new SpatialIndexException("Transformation Exception:
" + geometryLiteral + ". " + ex.getMessage());
- }
-
- }
- }
- return items;
- }
-
- /**
- *
- * @param model
- * @param srsURI
- * @return Geo predicate objects prepared for adding to SpatialIndex.
- */
- private static Collection<SpatialIndexItem>
getGeoPredicateIndexItems(Model model, String srsURI) throws
SpatialIndexException {
- List<SpatialIndexItem> items = new ArrayList<>();
- ResIterator resIt =
model.listResourcesWithProperty(SpatialExtension.GEO_LAT_PROP);
-
- while (resIt.hasNext()) {
- Resource feature = resIt.nextResource();
-
- Literal lat =
feature.getRequiredProperty(SpatialExtension.GEO_LAT_PROP).getLiteral();
- Literal lon =
feature.getProperty(SpatialExtension.GEO_LON_PROP).getLiteral();
- if (lon == null) {
- LOGGER.warn("Geo predicates: latitude found but not longitude.
" + feature);
- continue;
- }
-
- Literal latLonPoint = ConvertLatLon.toLiteral(lat.getFloat(),
lon.getFloat());
- GeometryWrapper geometryWrapper =
GeometryWrapper.extract(latLonPoint);
-
- try {
- //Ensure all entries in the target SRS URI.
- GeometryWrapper transformedGeometryWrapper =
geometryWrapper.convertSRS(srsURI);
-
- Envelope envelope = transformedGeometryWrapper.getEnvelope();
- SpatialIndexItem item = new SpatialIndexItem(envelope,
feature);
- items.add(item);
- } catch (FactoryException | MismatchedDimensionException |
TransformException ex) {
- throw new SpatialIndexException("Transformation Exception: " +
geometryWrapper.getLexicalForm() + ". " + ex.getMessage());
- }
- }
- return items;
- }
-
- /**
- * Load a SpatialIndex from file.<br>
- * Index will be built and empty if file does not exist or is null.
- *
- * @param spatialIndexFile
- * @return Built Spatial Index.
- * @throws SpatialIndexException
- */
- public static final SpatialIndex load(File spatialIndexFile) throws
SpatialIndexException {
-
- if (spatialIndexFile != null && spatialIndexFile.exists()) {
- LOGGER.info("Loading Spatial Index - Started: {}",
spatialIndexFile.getAbsolutePath());
- //Cannot directly store the SpatialIndex due to Resources not
being serializable, use SpatialIndexStorage class.
- try (ObjectInputStream in = new ObjectInputStream(new
FileInputStream(spatialIndexFile))) {
- SpatialIndexStorage storage = (SpatialIndexStorage)
in.readObject();
-
- SpatialIndex spatialIndex = storage.getSpatialIndex();
- LOGGER.info("Loading Spatial Index - Completed: {}",
spatialIndexFile.getAbsolutePath());
- return spatialIndex;
- } catch (ClassNotFoundException | IOException ex) {
- throw new SpatialIndexException("Loading Exception: " +
ex.getMessage(), ex);
- }
- } else {
- return new SpatialIndex();
- }
- }
-
- /**
- * Save SpatialIndex contents to file.
- *
- * @param spatialIndexFileURI
- * @param spatialIndexItems
- * @param srsURI
- * @throws SpatialIndexException
- */
- public static final void save(String spatialIndexFileURI,
Collection<SpatialIndexItem> spatialIndexItems, String srsURI) throws
SpatialIndexException {
- save(new File(spatialIndexFileURI), spatialIndexItems, srsURI);
- }
-
- /**
- * Save SpatialIndex contents to file.
+ * The default graph can be referenced with null or any value for which
{@link Quad#isDefaultGraph()} returns true.
+ * The union graph (= all named graphs but not the default graph) can be
referenced with {@link Quad#unionGraph}.
*
- * @param spatialIndexFile
- * @param spatialIndexItems
- * @param srsURI
- * @throws SpatialIndexException
+ * @param searchEnvelope
+ * @param graph
+ * @return
Review Comment:
Incomplete javadoc. `@return` needs a type.
##########
jena-geosparql/src/main/java/org/apache/jena/geosparql/spatial/index/v1/SpatialIndexV1.java:
##########
@@ -0,0 +1,577 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jena.geosparql.spatial.index.v1;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.invoke.MethodHandles;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.jena.atlas.RuntimeIOException;
+import org.apache.jena.atlas.io.IOX;
+import org.apache.jena.geosparql.configuration.GeoSPARQLOperations;
+import org.apache.jena.geosparql.implementation.GeometryWrapper;
+import org.apache.jena.geosparql.implementation.SRSInfo;
+import org.apache.jena.geosparql.implementation.registry.SRSRegistry;
+import org.apache.jena.geosparql.implementation.vocabulary.Geo;
+import org.apache.jena.geosparql.implementation.vocabulary.SRS_URI;
+import org.apache.jena.geosparql.implementation.vocabulary.SpatialExtension;
+import org.apache.jena.geosparql.spatial.ConvertLatLon;
+import org.apache.jena.geosparql.spatial.SpatialIndex;
+import org.apache.jena.geosparql.spatial.SpatialIndexException;
+import org.apache.jena.geosparql.spatial.SpatialIndexItem;
+import org.apache.jena.geosparql.spatial.SpatialIndexStorage;
+import org.apache.jena.geosparql.spatial.index.v2.SpatialIndexUtils;
+import org.apache.jena.query.Dataset;
+import org.apache.jena.query.DatasetFactory;
+import org.apache.jena.query.ReadWrite;
+import org.apache.jena.rdf.model.Literal;
+import org.apache.jena.rdf.model.Model;
+import org.apache.jena.rdf.model.NodeIterator;
+import org.apache.jena.rdf.model.RDFNode;
+import org.apache.jena.rdf.model.ResIterator;
+import org.apache.jena.rdf.model.Resource;
+import org.apache.jena.rdf.model.Statement;
+import org.apache.jena.rdf.model.StmtIterator;
+import org.apache.jena.sparql.engine.ExecutionContext;
+import org.apache.jena.sparql.util.Context;
+import org.apache.jena.sparql.util.ModelUtils;
+import org.apache.jena.util.iterator.ExtendedIterator;
+import org.locationtech.jts.geom.Envelope;
+import org.locationtech.jts.index.strtree.STRtree;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.referencing.operation.TransformException;
+import org.opengis.util.FactoryException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * SpatialIndex for testing bounding box collisions between geometries within a
+ * Dataset.<br>
+ * Queries must be performed using the same SRS URI as the SpatialIndex.<br>
+ * The SpatialIndex is added to the Dataset Context when it is built.<br>
+ * QueryRewriteIndex is also stored in the SpatialIndex as its content is
+ * Dataset specific.
+ */
+@Deprecated /** Superseded by {@link SpatialIndex} and {@link
SpatialIndexPerGraph}. */
Review Comment:
There isn't a `SpatialIndexPerGraph`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]