MySQL was a bit late to the geospatial party compared to other databases like Postgres, but with the 5.6 and then the 5.7 releases a lot of new GIS features were finally implemented. For instance in 5.7 we got, among other:

`ST_Distance_Sphere`

to compute the distance between two points on a sphere.- Spatial indexes for InnoDB
- GeoJSON integration which is, quoting from the RFC, “a geospatial data interchange format based on JSON.”

There’s a lot of interesting things we can now accomplish using these new fonctionnalities. Today I’ll showcase a very simple example on how to do a search using a Polygonand a Point. The goal here will be to answer the question “is this point in this city?”.

## Defining Points

First let’s create a “places” table with a name and a set of coordinates. However, instead of storing a latitude and a longitude as two different floats I’ll use a `Point`

.

Then let’s add a couple of places in Paris and one in New York for very basic testing. The way to store a new `Point`

is very straighforward:

## Filtering

Let’s then try to answer the question “what places in my database are in Paris?”.

### Filtering With `ST_Distance_Sphere`

First let’s try to use MySQL’s `ST_Distance_Sphere`

to find the distance between two points. Let’s use the Louvre’s coordinates (48.861105, 2.335337) which is in the center of Paris. We can easily compute the distance using `ST_Distance_Sphere`

.

This gives us:

```
Eiffel Tower 4629.968479838098
Pere Lachaise 6598.960247905806
Brooklyn 8500637.22140377
```

The distance returned is in metters, so everything checks out. If we want to see all points that are less than 10km from the Louvre, we can do:

This is a pretty good approximation to being in Paris, but that’s not perfect. What if I wanted to know if a point was really in Paris and not just close to the center of Paris?

### Filtering With a Polygon and `ST_CONTAINS`

First let’s define a very basic shape enclosing Paris. The coordinates I’ll be using here are a very rough approximation and I only define a rectangle, but that’ll work for this example:

*If you look closer, you’ll notice that the last point is the same as the first one and we have 5 points. This is because we need to “close” the polygon.*

To double check the result, we can use Sequel Pro’s preview feature and confirm how it looks:

Then we can use `ST_CONTAINS`

to ask all the places contained in the `@paris`

polygon:

Of course I could have skipped the step where I defined `@paris`

and called `POLYGON`

directly in the query.

## Performances

Geospacial functions are fun to play with and since we can now use spatial indexes in InnoDB, they become actually usable in production. I won’t get into performances in this article, but I recommend reading the Percona article “New GIS Features in MySQL 5.7”.

Since you scrolled this far, you might be interested in some other things I wrote: