Skip to content

Instantly share code, notes, and snippets.

@Tylerian
Last active November 13, 2023 18:33
Show Gist options
  • Save Tylerian/b2eebf5a384a30d0b642cb43f36f422a to your computer and use it in GitHub Desktop.
Save Tylerian/b2eebf5a384a30d0b642cb43f36f422a to your computer and use it in GitHub Desktop.
ST_DWithin function implementation for MySQL 8.0
-- Made by Jairo Tylera
-- (github.com/Tylerian)
-- (c) 2019 - present
-- Released under MIT X11 License
CREATE
DEFINER=`root`@`localhost`
FUNCTION
`ST_Epgs3857_DWithin`(p1 POINT, p2 POINT, distance_mts FLOAT)
RETURNS
tinyint(4)
DETERMINISTIC
BEGIN
DECLARE bounds POLYGON;
SET bounds = ST_Epgs3857_Expand(p2, distance_mts);
RETURN ST_Contains(bounds, p1);
END
-- Made by Jairo Tylera
-- (github.com/Tylerian)
-- (c) 2019 - present
-- Released under MIT X11 License
CREATE
DEFINER=`root`@`localhost`
FUNCTION
`ST_Epgs3857_Expand`(point POINT, radius INTEGER)
RETURNS
polygon
DETERMINISTIC
BEGIN
DECLARE hypo DOUBLE;
DECLARE midx DOUBLE;
DECLARE midy DOUBLE;
DECLARE poly VARCHAR(256);
DECLARE xmax DOUBLE;
DECLARE xmin DOUBLE;
DECLARE ymax DOUBLE;
DECLARE ymin DOUBLE;
SET midx = ST_X(point);
SET midy = ST_Y(point);
SET hypo = SQRT(POW(radius / COS(midy * PI() / 180), 2) * 2);
SET xmin = ROUND(midx - hypo, 2);
SET xmax = ROUND(midx + hypo, 2);
SET ymin = ROUND(midy - hypo, 2);
SET ymax = ROUND(midy + hypo, 2);
SET poly = CONCAT('POLYGON((',
xmin, ' ', ymin, ',',
xmin, ' ', ymax, ',',
xmax, ' ', ymax, ',',
xmax, ' ', ymin, ',',
xmin, ' ', ymin, '))');
RETURN ST_PolyFromText(poly, 3857);
END
-- Made by Jairo Tylera
-- (github.com/Tylerian)
-- (c) 2019 - present
-- Released under MIT X11 License
CREATE
DEFINER=`root`@`localhost`
FUNCTION
`ST_Epgs3857_To_Epgs4326`(point POINT)
RETURNS
point
DETERMINISTIC
BEGIN
DECLARE lat DOUBLE;
DECLARE lon DOUBLE;
DECLARE shift DOUBLE;
DECLARE x DOUBLE;
DECLARE y DOUBLE;
SET x = ST_X(point);
SET y = ST_Y(point);
SET shift = 20037508.342789244;
SET lon = (x / shift) * 180.0;
SET lat = (y / shift) * 180.0;
SET lat = 180.0 / PI() * (2.0 * ATAN(EXP(lat * PI() / 180.0)) - PI() / 2.0);
RETURN ST_PointFromText(CONCAT('POINT(', ROUND(lat, 5), ' ', ROUND(lon, 5), ')'), 4326);
END
-- Made by Jairo Tylera
-- (github.com/Tylerian)
-- (c) 2019 - present
-- Released under MIT X11 License
CREATE
DEFINER=`root`@`localhost`
FUNCTION
`ST_Epgs4326_To_Epgs3857`(point POINT)
RETURNS
point
DETERMINISTIC
BEGIN
DECLARE lat DOUBLE;
DECLARE lon DOUBLE;
DECLARE shift DOUBLE;
DECLARE x DOUBLE;
DECLARE y DOUBLE;
SET lat = ST_Latitude(point);
SET lon = ST_Longitude(point);
SET shift = 20037508.342789244;
SET x = lon * shift / 180.0;
SET y = LOG(TAN((90.0 + lat) * PI() / 360.0)) / (PI() / 180.0);
SET y = y * shift / 180.0;
RETURN ST_PointFromText(CONCAT('POINT(', ROUND(x, 2), ' ', ROUND(y, 2), ')'), 3857);
END
@pasmat
Copy link

pasmat commented Aug 24, 2023

this checks if is within bounding rectangle, and not within distance, which is circular

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment