Attention! Do you have any ideas for reorganizing and updating the Mapki? Please leave a note here. Thank you!

Spatial Data in MySQL

From Google Mapki

Jump to: navigation, search

Setting up the field

MySQL 4.1 introduced datatypes that are designed to hold geospatial data. It also allows you to use special geospatial functions to pull back points based upon that data.

For example, you can supply the points of a polygon and run a query to pull back all points within that polygon or all polylines that fall within that polygon or go inside it.

A good reference is MySQL documentation which seems to clearly explain how to set up the tables, but is less clear on insertion of data.

The GEOMETRY datatype is a binary ("WKB") format, to convert to / from this to a text ("WKT") format, use:

AsText(<fieldname>) to convert from WKB to WKT
GeomFromText('<text>') to convert from WKT to WKB.

The format of WKT is:

For a point - POINT(x y)
For a line - LINESTRING(x y,x y,x y,...)
For a polygon - POLYGON(x1 y1,x2 y2,...,xn, yn, x1, y2)

To create a table with a geometry field in it:

CREATE TABLE `locations` (
  `location_id` int(10) NOT NULL auto_increment,
  `name` text NOT NULL,
  `point` geometry NOT NULL default \'\',
  PRIMARY KEY  (`location_id`),
  SPATIAL KEY `point` (`point`(32))
) ENGINE=MyISAM;

Inserting Data

Beware when using phpmyadmin or similar to edit a table with a geometry type field in it as it does not seem to be able to edit any of the fields as it is having problem with the binary format of the field.

Replace <lat> and <lng> with your lat and lng values

Inserting a point:

INSERT INTO `locations` (name, point) VALUES ("location name",GeomFromText('POINT(<lng> <lat>)'))

Inserting a line:

INSERT INTO `locations` (name, point) VALUES ("location name",GeomFromText('Linestring(<lng> <lat>,<lng> <lat>,<lng> <lat>,<lng> <lat>,...)')

Inserting a polygon:

INSERT INTO `locations` (name, point) VALUES ("location name","Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))")

Reading Data

Reading the geometry field is pointless.

Instead use something like:

SELECT name, AsText(point) AS point FROM locations WHERE 1

Spatial selects can also be used:

SELECT name, AsText(point) AS point FROM locations WHERE Intersects(point,GeomFromText('LineString(<lng> <lat>,<lng> <lat>,<lng> <lat>,...)'))

The lat, lng pairs are a line describing the area to be selected. AFAIK in 4.1 the code is bodged and only works properly with rectangles, but it should have full functionality at some point. Intersects is very useful for passing the bounds of the viewport (or, as I prefer the viewport area plus a "buffer" zone around the edge) and getting back all points or lines that reside in or cross the bounds area.

Personal tools