# Geospatial Capabilities
HEAVY.AI supports a subset of object types and functions for storing and writing queries for geospatial definitions.
## Geospatial Datatypes
| Type | Size | Example |
| --------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `LINESTRING` | Variable | A sequence of 2 or more points and the lines that connect them. For example: `LINESTRING(0 0,1 1,1 2)` |
| `MULTIPOLYGON` | Variable | A set of one or more polygons. For example:`MULTIPOLYGON(((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))` |
| `POINT` | Variable | A point described by two coordinates. When the coordinates are longitude and latitude, HEAVY.AI stores longitude first, and then latitude. For example: `POINT(0 0)` |
| `POLYGON` | Variable | A set of one or more rings (closed line strings), with the first representing the shape (external ring) and the rest representing holes in that shape (internal rings). For example: `POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1))` |
| MULTIPOINT | Variable | A set of one or more points. For example: MULTIPOINT((0 0), (1 1), (2 2)) |
| MULTILINESTRING | Variable | A set of one or more associated lines, each of two or more points. For example: MULTILINESTRING((0 0, 1 0, 2 0), (0 1, 1 1, 2 1)) |
For information about geospatial datatype sizes, see [Storage](/sql/data-definition-ddl/datatypes-and-fixed-encoding#storage) and [Compression](/sql/data-definition-ddl/datatypes-and-fixed-encoding#compression) in [Datatypes](/sql/data-definition-ddl/datatypes-and-fixed-encoding).
For more information on WKT primitives, see [Wikipedia: Well-known Text: Geometric objects](https://en.wikipedia.org/wiki/Well-known_text#Geometric_objects).
HEAVY.AI supports SRID 4326 ([WGS 84](https://en.wikipedia.org/wiki/World_Geodetic_System#WGS84)) and 900913 (Google Web Mercator), and 32601-32660,32701-32760 (Universal Transverse Mercator (UTM) Zones). When using geospatial fields, you set the SRID to determine which reference system to use. HEAVY.AI does not assign a default SRID.
```sql
CREATE TABLE simple_geo (
name TEXT ENCODING DICT(32),
location GEOMETRY(POINT,4326)
);
```
If you do not set the SRID of the geo field in the table, you can set it in a SQL query using `ST_SETSRID(column_name, SRID)`. For example, `ST_SETSRID(a.pt,4326)`.
Return a point constructed on the fly from the provided coordinate values. Constant coordinates result in construction of a POINT literal.
Example: ST\_Contains(poly4326, ST\_SetSRID(ST\_Point(lon, lat), 4326))
Returns a geometry covering all points within a specified distance from the input geometry. Performed by the GEOS module. The output is currently limited to the MULTIPOLYGON type.
Calculations are in the units of the input geometry’s SRID. Buffer distance is expressed in the same units.
Example:
SELECT ST\_Buffer('LINESTRING(0 0, 10 0, 10 10)', 1.0);
Special processing is automatically applied to WGS84 input geometries (SRID=4326) to limit buffer distortion:
Example:
Build 10-meter buffer geometries (SRID=4326) with limited distortion:
SELECT ST\_Buffer(poly4326, 10.0) FROM tbl;
Returns a geometry with its coordinates transformed to a different spatial reference. Currently, WGS84 to Web Mercator transform is supported. For example:ST\_DISTANCE(
ST\_TRANSFORM(ST\_GeomFromText('POINT(-71.064544 42.28787)', 4326), 900913),
ST\_GeomFromText('POINT(-13189665.9329505 3960189.38265416)', 900913))
ST\_TRANSFORM is not currently supported in projections. It can be used only to transform geo inputs to other functions, such as ST\_DISTANCE.
Set the SRID to a specific integer value. For example:
ST\_TRANSFORM(
ST\_SETSRID(ST\_GeomFromText('POINT(-71.064544 42.28787)'), 4326), 900913 )
Returns a geometry representing an intersection of two geometries; that is, the section that is shared between the two input geometries. Performed by the GEOS module.
The output is currently limited to MULTIPOLYGON type, because HEAVY.AI does not support mixed geometry types within a geometry column, and ST\_INTERSECTION can potentially return points, lines, and polygons from a single intersection operation.
Lower-dimension intersecting features such as points and line strings are returned as very small buffers around those features. If needed, true points can be recovered by applying the ST\_CENTROID method to point intersection results. In addition, ST\_PERIMETER/2 of resulting line intersection polygons can be used to approximate line length.
Empty/NULL geometry outputs are not currently supported.
Examples:SELECT ST\_Intersection('POLYGON((0 0,3 0,3 3,0 3))', 'POLYGON((1 1,4 1,4 4,1 4))');SELECT ST\_Area(ST\_Intersection(poly, 'POLYGON((1 1,3 1,3 3,1 3,1 1))')) FROM tbl;
Returns a geometry representing the portion of the first input geometry that does not intersect with the second input geometry. Performed by the GEOS module. Input order is important; the return geometry is always a section of the first input geometry.
The output is currently limited to MULTIPOLYGON type, for the same reasons described in ST\_INTERSECTION. Similar post-processing methods can be applied if needed.
Empty/NULL geometry outputs are not currently supported.
Examples:SELECT ST\_Difference('POLYGON((0 0,3 0,3 3,0 3))', 'POLYGON((1 1,4 1,4 4,1 4))');SELECT ST\_Area(ST\_Difference(poly, 'POLYGON((1 1,3 1,3 3,1 3,1 1))')) FROM tbl;
Returns a geometry representing the union (or combination) of the two input geometries. Performed by the GEOS module.
The output is currently limited to MULTIPOLYGON type for the same reasons described in ST\_INTERSECTION. Similar post-processing methods can be applied if needed.
Empty/NULL geometry outputs are not currently supported.
Examples:SELECT ST\_UNION('POLYGON((0 0,3 0,3 3,0 3))', 'POLYGON((1 1,4 1,4 4,1 4))');SELECT ST\_AREA(ST\_UNION(poly, 'POLYGON((1 1,3 1,3 3,1 3,1 1))')) FROM tbl;
Returns shortest planar distance between geometries. For example:ST\_DISTANCE(poly1, ST\_GeomFromText('POINT(0 0)'))
Returns shortest geodesic distance between two points, in meters, if given two point geographies. Point geographies can be specified through casts from point geometries or as literals. For example:ST\_DISTANCE(
CastToGeography(p2),
ST\_GeogFromText('POINT(2.5559 49.0083)', 4326))
SELECT a.name,
ST\_DISTANCE(
CAST(a.pt AS GEOGRAPHY),
CAST(b.pt AS GEOGRAPHY)
) AS dist\_meters
FROM starting\_point a, destination\_points b;
You can also calculate the distance between a POLYGON and a POINT. If both fields use SRID 4326, then the calculated distance is in 4326 units (degrees). If both fields use SRID 4326, and both are transformed into 900913, then the results are in 900913 units (meters).
The following SQL code returns the names of polygons where the distance between the point and polygon is less than 1,000 meters.
SELECT a.poly\_name FROM poly a, point b WHERE ST\_DISTANCE(
ST\_TRANSFORM(b.location,900913),
ST\_TRANSFORM(a.heavyai\_geo,900913)) \< 1000;
Returns TRUE if the first input geometry and the second input geometry are spatially equal; that is, they occupy the same space. Different orderings of points can be accepted as equal if they represent the same geometry structure.
POINTs comparison is performed natively. All other geometry comparisons are performed by GEOS.
If input geometries are both uncompressed or compressed, all comparisons to identify equality are precise. For mixed combinations, the comparisons are performed with a compression-specific tolerance that allows recognition of equality despite subtle precision losses that the compression may introduce. Note: Geo columns and literals with SRID=4326 are compressed by default.
Examples:SELECT COUNT(\*) FROM tbl WHERE ST\_EQUALS('POINT(2 2)', pt);SELECT ST\_EQUALS('POLYGON ((0 0,1 0,0 1))', 'POLYGON ((0 0,0 0.5,0 1,1 0,0 0))');
Returns longest planar distance between geometries. In effect, this is the diameter of a circle that encloses both geometries.For example:
Currently supported variants:
| | `ST_CONTAINS` |Returns true if the first geometry object contains the second object. For example:
You can also use ST\_CONTAINS to:
SELECT count(\*) FROM geo1 WHERE ST\_CONTAINS(poly1, 'POINT(0 0)');SELECT a.name FROM polys a, points b WHERE ST\_CONTAINS(a.heavyai\_geo, b.location);SELECT name FROM poly WHERE ST\_CONTAINS(heavyai\_geo, ST\_GeomFromText('POINT(-98.4886935 29.4260508)', 4326));Returns true if two geometries intersect spatially, false if they do not share space. For example:
SELECT ST\_INTERSECTS(
'POLYGON((0 0, 2 0, 2 2, 0 2, 0 0))',
'POINT(1 1)'
) FROM tbl;
Returns the area of planar areas covered by POLYGON and MULTIPOLYGON geometries. For example:
SELECT ST\_AREA(
'POLYGON((1 0, 0 1, -1 0, 0 -1, 1 0),(0.1 0, 0 0.1, -0.1 0, 0 -0.1, 0.1 0))'
) FROM tbl;
ST\_AREA does not support calculation of geographic areas, but rather uses planar coordinates. Geographies must first be projected in order to use ST\_AREA. You can do this ahead of time before import or at runtime, ideally using an equal area projection (for example, a national equal-area Lambert projection). The area is calculated in the projection's units. For example, you might use Web Mercator runtime projection to get the area of a polygon in square meters:
ST\_AREA(
ST\_TRANSFORM(
ST\_GeomFromText(
'POLYGON((-76.6168198439371 39.9703199555959,
-80.5189990254673 40.6493554919257,
-82.5189990254673 42.6493554919257,
-76.6168198439371 39.9703199555959)
)', 4326
),
900913)
)
\\
Web Mercator is not an equal area projection, however. Unless compensated by a scaling factor, Web Mercator areas can vary considerably by latitude.
| | `ST_PERIMETER` |Returns the cartesian perimeter of POLYGON and MULTIPOLYGON geometries. For example:SELECT ST\_PERIMETER('POLYGON(
(1 0, 0 1, -1 0, 0 -1, 1 0),
(0.1 0, 0 0.1, -0.1 0, 0 -0.1, 0.1 0)
)'
)from tbl;
It will also return the geodesic perimeter of POLYGON and MULTIPOLYGON geometries. For example:
SELECT ST\_PERIMETER(
ST\_GeogFromText(
'POLYGON(
(-76.6168198439371 39.9703199555959,
-80.5189990254673 40.6493554919257,
-82.5189990254673 42.6493554919257,
-76.6168198439371 39.9703199555959)
)',
4326)
)from tbl;
Returns the cartesian length of LINESTRING geometries. For example:SELECT ST\_LENGTH('LINESTRING(1 0, 0 1, -1 0, 0 -1, 1 0)') FROM tbl;
It also returns the geodesic length of LINESTRING geographies. For example:
SELECT ST\_LENGTH(
ST\_GeogFromText('LINESTRING(
-76.6168198439371 39.9703199555959,
-80.5189990254673 40.6493554919257,
-82.5189990254673 42.6493554919257)',
4326)
) FROM tbl;
Returns true if geometry A is completely within geometry B. For example the following SELECT statement returns true:
SELECT ST\_WITHIN(
'POLYGON ((1 1, 1 2, 2 2, 2 1))',
'POLYGON ((0 0, 0 3, 3 3, 3 0))'
) FROM tbl;
Returns true if the geometries are within the specified distance of each one another. Distance is specified in units defined by the spatial reference system of the geometries. For example:SELECT ST\_DWITHIN(
'POINT(1 1)',
'LINESTRING (1 2,10 10,3 3)', 2.0
) FROM tbl;ST\_DWITHIN supports geodesic distances between geographies, currently limited to geographic points. For example, you can check whether Los Angeles and Paris, specified as WGS84 geographic point literals, are within 10,000km of one another.
SELECT ST\_DWITHIN(
ST\_GeogFromText(
'POINT(-118.4079 33.9434)', 4326),
ST\_GeogFromText('POINT(2.5559 49.0083)',
4326 ),
10000000.0) FROM tbl;
Returns true if the geometries are fully within the specified distance of one another. Distance is specified in units defined by the spatial reference system of the geometries. For example:SELECT ST\_DFULLYWITHIN(
'POINT(1 1)',
'LINESTRING (1 2,10 10,3 3)',
10.0) FROM tbl;
This function supports:
ST\_DFULLYWITHIN(POINT, LINESTRING, distance)ST\_DFULLYWITHIN(LINESTRING, POINT, distance)
Returns true if the geometries are spatially disjoint (that is, the geometries do not overlap or touch. For example:
SELECT ST\_DISJOINT(
'POINT(1 1)',
'LINESTRING (0 0,3 3)'
) FROM tbl;