Geospatial queries for Point and LineString

How to perform geospatial queries for Point and LineString.

Perform geospatial queries for Point and LineString.

Create a CQL table with geospatial columns

For geospatial field types, enclose the data type name in single quotes when creating or altering a table. For example:
CREATE TABLE test (
id text PRIMARY KEY, 
point 'PointType', 
linestring 'LineStringType');

Create a search index

Search indexes do not automatically configure geospatial data fields. First add the index to create a search index schema:
CREATE SEARCH INDEX ON test WITH OPTIONS { lenient: true};

Defining schemas for geospatial Point and LineString types

Add the Solr field type definition for geospatial coordinates:
ALTER SEARCH INDEX SCHEMA ON test 
ADD types.fieldType[ @name='rpt',
                     @class='solr.SpatialRecursivePrefixTreeFieldType',
                     @geo='false',
                     @worldBounds='ENVELOPE(-1000, 1000, 1000, -1000)',
                     @maxDistErr='0.001',
                     @distanceUnits='degrees' ];
Add the fields, specifying the CQL column name as the field name:
ALTER SEARCH INDEX SCHEMA ON test 
ADD fields.field[ @name='point', 
                  @type='rpt', 
                  @indexed='true', 
                  @stored='true' ];
ALTER SEARCH INDEX SCHEMA ON test 
ADD fields.field[ @name='linestring', 
                  @type='rpt', 
                  @indexed='true', 
                  @stored='true' ];
Show the pending schema and verify that it is correct against the following example:
DESC PENDING SEARCH INDEX SCHEMA ON test;
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<schema name="autoSolrSchema" version="1.5">
  <types>
    <fieldType class="org.apache.solr.schema.StrField" name="StrField"/>
    <fieldType class="solr.SpatialRecursivePrefixTreeFieldType" distanceUnits="degrees" geo="false" maxDistErr="0.001" name="rpt" worldBounds="ENVELOPE(-1000, 1000, 1000, -1000)"/>
  </types>
  <fields>
    <field indexed="true" multiValued="false" name="id" type="StrField"/>
    <field indexed="true" name="point" stored="true" type="rpt"/>
    <field indexed="true" name="linestring" stored="true" type="rpt"/>
  </fields>
  <uniqueKey>id</uniqueKey>
</schema>
Update the active schema and configuration by overwriting them with the pending changes:
RELOAD SEARCH INDEX ON test;

Inserting or updating geospatial data

To insert or update data in the database, specify geotypes in the INSERT or UPDATE command. For example:
INSERT INTO test (id, point, linestring) 
VALUES ('1', 'POINT(5 50)', 'LINESTRING (30 10, 10 30, 40 40)' );
INSERT INTO test (id, point, linestring) 
VALUES ('2', 'POINT(100 100)', 'LINESTRING (50 20, 20 40, 50 50)' );

Querying geospatial data

Find points within a 10 unit radius from point (4, 49):
SELECT * FROM test 
WHERE solr_query= '{ "q":"*:*", "fq":"point:\"IsWithin(BUFFER(POINT(4.0 49.0), 10.0))\"" }';
id | linestring                                   | point            | solr_query
----+----------------------------------------------+------------------+------------
  1 | LINESTRING (30.0 10.0, 10.0 30.0, 40.0 40.0) | POINT (5.0 50.0) |       null

(1 rows)
Find linestring that contains the point (10, 30):
SELECT * FROM test WHERE solr_query='linestring:"Intersects(POINT(10 30))"';
id | linestring                                   | point            | solr_query
----+----------------------------------------------+------------------+------------
  1 | LINESTRING (30.0 10.0, 10.0 30.0, 40.0 40.0) | POINT (5.0 50.0) |       null

(1 rows)
Find all points on a linestring and return a heatmap:
SELECT * FROM test 
WHERE solr_query='{"q":"id:*", "facet": {"heatmap": "point"}}';
facet_heatmaps
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{
    "point":{
        "gridLevel":4,
        "columns":16,
        "rows":16,
        "minX":-1000.0,
        "maxX":1000.0,
        "minY":-1000.0,
        "maxY":1000.0,
        "counts_ints2D":[
            null,
            null,
            null,
            [0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],
            null,
            [0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,7,3,0,0,0,0,0,0],
            null,
            null,
            null,
            null,
            null,
            null,
            null,
            null
        ]
    }
}
See the full list of parameters: https://lucene.apache.org/solr/guide/6_6/spatial-search.html#SpatialSearch-HeatmapFaceting.
See this tutorial for details on how to index and query geospatial Polygons and MultiPolygons.