I have table as follows the schema below.
CREATE TABLE `gdata` (
`alarmTypeID` tinyint(4) NOT NULL DEFAULT '0',
`fleetID` smallint(11) NOT NULL,
`fleetGroupID` smallint(11) DEFAULT NULL,
`fleetSubGroupID` smallint(11) DEFAULT NULL,
`deviceID` mediumint(11) NOT NULL,
`vehicleID` mediumint(11) NOT NULL,
`gDateTime` datetime NOT NULL,
`insertDateTime` datetime NOT NULL,
`latitude` float NOT NULL,
`longitude` float NOT NULL,
`speed` smallint(11) NOT NULL,
(see full text)
ALTER TABLE `gdata`
ADD PRIMARY KEY (`vehicleID`,`gDateTime`,`alarmTypeID`),
ADD KEY `gDateTime` (`gDateTime`),
ADD KEY `fleetID` (`fleetID`,`vehicleID`,`gDateTime`);
COMMIT;
My issue now is that I can run a query as below EXPLAIN select vehicleID,latitude,longitude from gdata where gDateTime between '2017-07-03 00:00:00' and '2017-07-04 00:00:00'
and the results of the explains is
1 SIMPLE gdata range gDateTime gDateTime 5 1251 100.00 Using index condition
I have the following function which works to test if the a latitude and longitude is withing a rectangle.
DELIMITER $$
--
-- Functions
--
CREATE DEFINER=`root`@`localhost`
FUNCTION `geoProcessor`(pt POINT, mp MULTIPOLYGON)
RETURNS int(1)
DETERMINISTIC
BEGIN
DECLARE str, xy TEXT;
DECLARE x, y, p1x, p1y, p2x, p2y, m, xinters DECIMAL(16, 13) DEFAULT 0;
DECLARE counter INT DEFAULT 0;
DECLARE p, pb, pe INT DEFAULT 0;
SELECT MBRWithin(pt, mp) INTO p;
IF p != 1 OR ISNULL(p) THEN
RETURN p;
END IF;
SELECT X(pt), Y(pt), ASTEXT(mp) INTO x, y, str;
SET str = REPLACE(str, 'POLYGON((','');
SET str = REPLACE(str, '))', '');
SET str = CONCAT(str, ',');
SET pb = 1;
SET pe = LOCATE(',', str);
SET xy = SUBSTRING(str, pb, pe - pb);
SET p = INSTR(xy, ' ');
SET p1x = SUBSTRING(xy, 1, p - 1);
SET p1y = SUBSTRING(xy, p + 1);
SET str = CONCAT(str, xy, ',');
WHILE pe > 0 DO
SET xy = SUBSTRING(str, pb, pe - pb);
SET p = INSTR(xy, ' ');
SET p2x = SUBSTRING(xy, 1, p - 1);
SET p2y = SUBSTRING(xy, p + 1);
IF p1y < p2y THEN SET m = p1y; ELSE SET m = p2y; END IF;
IF y > m THEN
IF p1y > p2y THEN SET m = p1y; ELSE SET m = p2y; END IF;
IF y <= m THEN
IF p1x > p2x THEN SET m = p1x; ELSE SET m = p2x; END IF;
IF x <= m THEN
IF p1y != p2y THEN
SET xinters = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x;
END IF;
IF p1x = p2x OR x <= xinters THEN
SET counter = counter + 1;
END IF;
END IF;
END IF;
END IF;
SET p1x = p2x;
SET p1y = p2y;
SET pb = pe + 1;
SET pe = LOCATE(',', str, pb);
END WHILE;
RETURN counter % 2;
END$$
DELIMITER ;
My issue now I want to find out which vehicle is within a rectangle within a time range value. I have to run two separate queries to first run the first queries get the lat, long value then test if its within the rectangle using the second query. How to opmtimise this?
SELECT
does not mention the bounding box, augment it to do so. TheFUNCTION
talks about one point in one polygon, not multiple points in a 'rectangle'. Bottom line: What is the real question? – Rick James Jul 5 '17 at 18:58