diff --git a/infinispan-remote/spatial-queries/pom.xml b/infinispan-remote/spatial-queries/pom.xml
new file mode 100644
index 0000000..ae3093d
--- /dev/null
+++ b/infinispan-remote/spatial-queries/pom.xml
@@ -0,0 +1,72 @@
+
+
+ 4.0.0
+
+ infinispan-simple-tutorials
+ org.infinispan.tutorial.simple
+ 1.0.0-SNAPSHOT
+ ../../pom.xml
+
+ infinispan-simple-tutorials-spatial-queries
+ Infinispan Simple Tutorials: Spatial Queries
+
+
+
+
+ org.infinispan
+ infinispan-bom
+
+ 15.1.0-SNAPSHOT
+ pom
+ import
+
+
+
+
+
+
+ org.infinispan.tutorial.simple
+ connect-to-infinispan-server
+ ${project.version}
+
+
+ org.junit.jupiter
+ junit-jupiter
+ test
+
+
+ org.assertj
+ assertj-core
+ 3.26.3
+ test
+
+
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+
+
+
+ exec
+
+
+
+
+ java
+
+ -Djava.net.preferIPv4Stack=true
+ -Djava.util.logging.config.file=src/main/resources/logging.properties
+ -classpath
+
+ org.infinispan.tutorial.simple.remote.spatial.InfinispanSpatialQueries
+
+
+
+
+
+
diff --git a/infinispan-remote/spatial-queries/src/main/java/org/infinispan/tutorial/simple/remote/spatial/Hiking.java b/infinispan-remote/spatial-queries/src/main/java/org/infinispan/tutorial/simple/remote/spatial/Hiking.java
new file mode 100644
index 0000000..ecbcd2a
--- /dev/null
+++ b/infinispan-remote/spatial-queries/src/main/java/org/infinispan/tutorial/simple/remote/spatial/Hiking.java
@@ -0,0 +1,13 @@
+package org.infinispan.tutorial.simple.remote.spatial;
+
+import org.infinispan.api.annotations.indexing.GeoField;
+import org.infinispan.api.annotations.indexing.Indexed;
+import org.infinispan.api.annotations.indexing.Keyword;
+import org.infinispan.commons.api.query.geo.LatLng;
+import org.infinispan.protostream.annotations.Proto;
+
+@Proto
+@Indexed
+public record Hiking(@Keyword String name, @GeoField LatLng start, @GeoField LatLng end) {
+
+}
diff --git a/infinispan-remote/spatial-queries/src/main/java/org/infinispan/tutorial/simple/remote/spatial/InfinispanSpatialQueries.java b/infinispan-remote/spatial-queries/src/main/java/org/infinispan/tutorial/simple/remote/spatial/InfinispanSpatialQueries.java
new file mode 100644
index 0000000..2d71e4e
--- /dev/null
+++ b/infinispan-remote/spatial-queries/src/main/java/org/infinispan/tutorial/simple/remote/spatial/InfinispanSpatialQueries.java
@@ -0,0 +1,228 @@
+package org.infinispan.tutorial.simple.remote.spatial;
+
+import static org.infinispan.query.remote.client.ProtobufMetadataManagerConstants.PROTOBUF_METADATA_CACHE_NAME;
+
+import java.net.URI;
+import java.util.List;
+
+import org.infinispan.client.hotrod.RemoteCache;
+import org.infinispan.client.hotrod.RemoteCacheManager;
+import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
+import org.infinispan.commons.api.query.Query;
+import org.infinispan.commons.api.query.QueryResult;
+import org.infinispan.commons.api.query.geo.LatLng;
+import org.infinispan.protostream.GeneratedSchema;
+import org.infinispan.tutorial.simple.connect.TutorialsConnectorHelper;
+
+/**
+ * Copied and adapted from Katia's org.infinispan.tutorial.simple.remote.query.InfinispanRemoteQuery to
+ * display spatial queries feature.
+ */
+public class InfinispanSpatialQueries {
+
+ public static final String MY_CACHE_NAME = "my-cache";
+
+ static RemoteCacheManager client;
+ static RemoteCache myCache;
+
+ private static final LatLng MILAN_COORDINATES = LatLng.of(45.4685, 9.1824);
+ private static final LatLng COMO_COORDINATES = LatLng.of(45.8064, 9.0852);
+ private static final LatLng BOLOGNA_COORDINATES = LatLng.of(44.4949, 11.3426);
+ private static final LatLng MY_COORDINATES = LatLng.of(41.90847031512531, 12.455633288333539);
+ private static final LatLng ROME_COORDINATES = LatLng.of(41.8967, 12.4822);
+ private static final LatLng VENICE_COORDINATES = LatLng.of(45.4404, 12.3160);
+ private static final LatLng SELVA_COORDINATES = LatLng.of(46.5560, 11.7559);
+
+ public static void main(String[] args) throws Exception {
+ connectToInfinispan();
+
+ addDataToCache();
+ withinCircle();
+ withinBox();
+ withinPolygon();
+ spatialProjection();
+ spatialOrderBy();
+ spatialProjection_OrderBy();
+ alternativeMapping_entityHavingMultipleGeoPoints();
+ alternativeMapping_entityHavingMultipleGeoFields();
+
+ disconnect(false);
+ }
+
+ static QueryResult withinCircle() {
+ Query query = myCache.query("from tutorial.Restaurant r where r.location " +
+ "within circle(:lat, :lon, :distance)");
+ query.setParameter("lat", MY_COORDINATES.latitude());
+ query.setParameter("lon", MY_COORDINATES.longitude());
+ query.setParameter("distance", 100);
+ QueryResult queryResult = query.execute();
+ // Print the results
+ System.out.println("COUNT " + queryResult.count().value());
+ System.out.println(queryResult.list());
+ return queryResult;
+ }
+
+ static QueryResult withinBox() {
+ Query query = myCache.query("from tutorial.Restaurant r where r.location " +
+ "within box(41.91, 12.45, 41.90, 12.46)");
+ QueryResult queryResult = query.execute();
+ // Print the results
+ System.out.println("COUNT " + queryResult.count().value());
+ System.out.println(queryResult.list());
+ return queryResult;
+ }
+
+ static QueryResult withinPolygon() {
+ Query query = myCache.query("from tutorial.Restaurant r where r.location " +
+ "within polygon((41.91, 12.45), (41.91, 12.46), (41.90, 12.46), (41.90, 12.46))");
+ QueryResult queryResult = query.execute();
+ // Print the results
+ System.out.println("COUNT " + queryResult.count().value());
+ System.out.println(queryResult.list());
+ return queryResult;
+ }
+
+ static List spatialProjection() {
+ Query