# Spatial relationships¶

Spatial databases can not only store geometry, they also provide the capabilities to compare *relationships between geometries*. Answering questions such as “Which are the closet bike racks to a park?” or “Where are the intersections of subway lines and streets?” is only possible by comparing geometries representing the bike racks, streets, and subway lines.

The next sections describe the various geometry comparison functions available with PostGIS.

## ST_Equals¶

**ST_Equals(geometry A, geometry B)** tests the spatial equality of two geometries.
**ST_Equals** returns TRUE if two geometries of the same type have identical x,y coordinate values, that is if the secondary shape is equal (identical) to the first shape.

Objects are equal to themselves.

```
SELECT ST_Equals( 'POINT(0 0)', 'POINT(0 0)' );
```

```
st_equals
-----------
t
```

Objects are equal to other objects that cover the same space (but might have different representations):

```
SELECT ST_Equals(
'LINESTRING(0 0,1 1)',
'LINESTRING(1 1,0.5 0.5,0 0)'
);
```

```
st_equals
-----------
t
```

There are other equality tests in PostGIS as well, that test for identical representations or bounds equality, refer to Equality for more information.

## Intersections¶

**ST_Intersects**, **ST_Crosses**, and **ST_Overlaps** test whether the interiors of the geometries intersect.

**ST_Intersects(geometry A, geometry B)** returns TRUE if the intersection any part of geometry A touches or overlaps with geometry B.

The opposite of **ST_Intersects** is **ST_Disjoint(geometry A , geometry B)**. If two geometries are disjoint, they do not intersect, and vice-versa.

Note

It is usually more efficient to test “not intersects” than to test “disjoint” because the intersects tests can be spatially indexed, while the disjoint test cannot.

For multipoint/polygon, multipoint/linestring, linestring/linestring, linestring/polygon, and linestring/multipolygon comparisons, **ST_Crosses(geometry A, geometry B)** returns TRUE if the intersection results in a geometry whose dimension is one less than the maximum dimension of the two source geometries. The intersection set must also be interior to both source geometries.

**ST_Overlaps(geometry A, geometry B)** compares two geometries of the same dimension and returns TRUE if the intersection set results in a geometry different from both but of the same dimension.

For example, again using the New York City subways and neighborhoods as an example, it is possible to determine a subway station’s neighborhood using the **ST_Intersects** function.

```
SELECT name, ST_AsText(the_geom)
FROM nyc_subway_stations
WHERE name = 'Broad St';
```

```
POINT(583571 4506714)
```

```
SELECT name, boroname
FROM nyc_neighborhoods
WHERE ST_Intersects(the_geom, ST_GeomFromText('POINT(583571 4506714)',26918));
```

```
name | boroname
--------------------+-----------
Financial District | Manhattan
```

## Touching¶

**ST_Touches(geometry A, geometry B)** tests whether two geometries touch at their boundaries, but do not intersect in their interiors. **ST_Touches** will return TRUE if either of the geometries’ boundaries intersect, or if only one of the geometry’s interiors intersects the other’s boundary.

## Containing¶

Although **ST_Within** and **ST_Contains** both test whether one geometry is fully within the other, **ST_Within** tests for the exact opposite result of **ST_Contains**.

**ST_Within(geometry A, geometry B)** returns TRUE if the first geometry is completely **within** the second geometry. **ST_Contains(geometry A, geometry B)** returns TRUE if the second geometry is completely **contained** by the first geometry.

## Distance¶

Identifying features that are within a certain distance of other features is a common requirement in spatial analysis. The **ST_Distance(geometry A, geometry B)** calculates the (shortest) distance between two geometries and returns the answer as a number (float). This is useful for actually reporting back the distance between objects.

```
SELECT ST_Distance(
ST_GeometryFromText('POINT(0 5)'),
ST_GeometryFromText('LINESTRING(-2 2, 2 2)'));
```

```
3
```

To test whether two objects are within a distance of one another, the **ST_DWithin** function provides an spatial index-accelerated TRUE/FALSE test. This will help answer questions such as “how many trees are within a 500 meter buffer of the road?”. You don’t have to calculate an actual buffer, you just have to test the distance relationship.

The following example will identify the streets within 10 meters of a given subway stop:

```
SELECT name
FROM nyc_streets
WHERE ST_DWithin(
the_geom,
ST_GeomFromText('POINT(583571 4506714)',26918),
10
);
```

```
name
--------------
Wall St
Broad St
Nassau St
```

For more information about geometry functions in PostGIS, please refer to the PostGIS Reference