This is not a complete answer at the moment, but rather an indication of what could be done. I originally worked through this in SQL Server (for visualization and then ported it to PostGIS. I have put bothe versions in.
Disclaimers
First, you will need to make lines from the points that you have collected.
At the moment I haven't included that, but have concentrated on getting minimal overlapping rotated (as per comments) rectangles.
The following is based on a single line, but can be changed to handle multiple lines with out to many problems.
I have done it based on units only and the rectangle I am generating is 200 units as it suited the dummy line I made. Feel free to add some some data to your question.
Due to the way SQL Server STDifference works I have reversed the order that I segment the line in.
Explanation
This is a recursive query for a single line currently. It segments the the line from the end of the line to the beginning into sections of 200 units. This can be look at as a very specific point reduction. The last segment is not currently extended, but could quite easily be.
Each of these segments is then turned into a square of 200 x 200 units (40,000 sq units).
PostGIS
/*
Altered to handle input from a geography datatype.
This means chopping and changing between types to get around restrictions
*/
WITH RECURSIVE SEGMENT_LINE(x1,y1,Ring,X2,Y2,myLine) AS (
SELECT
/*Initial coorindate for the line*/
ST_X(ST_PointN(myLine::Geometry,1)) X1, ST_Y(ST_PointN(myLine::Geometry,1)) Y1,
/*The ring for determining where to split line. ** NOT REQUIRED ** */
ST_ExteriorRing(ST_Buffer(ST_PointN(myLine::Geometry,1)::Geography,500 * 0.3048)::Geometry)::Geography Ring,
/*Case statements to deal with end of line*/
CASE WHEN ST_Intersects(ST_ExteriorRing(ST_Buffer(ST_PointN(myLine::Geometry,1)::Geography,500 * 0.3048)::Geometry),myLine::Geometry) THEN
ST_X(ST_Intersection(ST_ExteriorRing(ST_Buffer(ST_PointN(myLine::Geometry,1)::Geography,500 * 0.3048)::Geometry),myLine::Geometry))
ELSE
ST_X(ST_PointN(myLine::Geometry, -1))
END X2,
CASE WHEN ST_Intersects(ST_ExteriorRing(ST_Buffer(ST_PointN(myLine::Geometry,1)::Geography,500 * 0.3048)::Geometry),myLine::Geometry) THEN
ST_Y(ST_Intersection(ST_ExteriorRing(ST_Buffer(ST_PointN(myLine::Geometry,1)::Geography,500 * 0.3048)::Geometry),myLine::Geometry))
ELSE
ST_Y(ST_PointN(myLine::Geometry, -1))
END Y2,
/*Split and remove the first portion of the line. */
CASE WHEN ST_Intersects(ST_ExteriorRing(ST_Buffer(ST_PointN(myLine::Geometry,1)::Geography,500 * 0.3048)::Geometry),myLine) THEN
ST_GeometryN(ST_Split(
/*Nodes the line for the split at point. Deals with floating point errors*/
ST_LineMerge(ST_Split(myLine::Geometry,ST_ExteriorRing(ST_Buffer(ST_PointN(myLine::Geometry,1)::Geography,500 * 0.3048)::Geometry))),
ST_Intersection(ST_ExteriorRing(ST_Buffer(ST_PointN(myLine::Geometry,1)::Geography,500 * 0.3048)::Geometry),myLine::Geometry)
),2)::Geography
ELSE
NULL
END myLine
FROM (VALUES (
ST_GeographyFromText('SRID=4326;LINESTRING(-84.26929 39.18387,-84.26929 39.18389,-84.26921 39.18399,-84.26613 39.18531,-84.26585 39.18542,-84.24252 39.19028,
-84.24153 39.19059,-84.2408 39.19082,-84.23963 39.19123,-84.23803 39.19266,-84.23773 39.19336)'))
) AS Sample(myLine)
UNION ALL
SELECT
/*Initial coorindate for the line*/
ST_X(ST_PointN(myLine::Geometry,1)) X1, ST_Y(ST_PointN(myLine::Geometry,1)) Y1,
/*The ring for determining where to split line. ** NOT REQUIRED ***/
ST_ExteriorRing(ST_Buffer(ST_PointN(myLine::Geometry,1)::Geography,500 * 0.3048)::Geometry)::Geography Ring,
/*Case statements to deal with end of line*/
CASE WHEN ST_Intersects(ST_ExteriorRing(ST_Buffer(ST_PointN(myLine::Geometry,1)::Geography,500 * 0.3048)::Geometry),myLine::Geometry) THEN
ST_X(ST_Intersection(ST_ExteriorRing(ST_Buffer(ST_PointN(myLine::Geometry,1)::Geography,500 * 0.3048)::Geometry),myLine::Geometry))
ELSE
ST_X(ST_PointN(myLine::Geometry, -1))
END X2,
CASE WHEN ST_Intersects(ST_ExteriorRing(ST_Buffer(ST_PointN(myLine::Geometry,1)::Geography,500 * 0.3048)::Geometry),myLine::Geometry) THEN
ST_Y(ST_Intersection(ST_ExteriorRing(ST_Buffer(ST_PointN(myLine::Geometry,1)::Geography,500 * 0.3048)::Geometry),myLine::Geometry))
ELSE
ST_Y(ST_PointN(myLine::Geometry, -1))
END Y2,
/*Split and remove the first portion of the line. */
CASE WHEN ST_Intersects(ST_ExteriorRing(ST_Buffer(ST_PointN(myLine::Geometry,1)::Geography,500 * 0.3048)::Geometry),myLine) THEN
ST_GeometryN(ST_Split(
/*Nodes the line for the split at point. Deals with floating point errors*/
ST_LineMerge(ST_Split(myLine::Geometry,ST_ExteriorRing(ST_Buffer(ST_PointN(myLine::Geometry,1)::Geography,500 * 0.3048)::Geometry))),
ST_Intersection(ST_ExteriorRing(ST_Buffer(ST_PointN(myLine::Geometry,1)::Geography,500 * 0.3048)::Geometry),myLine::Geometry)
),2)::Geography
ELSE
NULL
END myLine
FROM SEGMENT_LINE
WHERE myLine is not null
)
SELECT X1, Y1, X2, Y2, Ring,
ST_MakeLine(ST_MakePoint( X1 , Y1 ),ST_MakePoint( X2 , Y2 )) seg,
ST_MakePolygon(
ST_MakeLine(ARRAY[
ST_MakePoint( X1 - (Y2 - Y1) / 2 , Y1 + (X2 - X1) / 2 ),
ST_MakePoint( X1 + (Y2 - Y1) / 2 , Y1 - (X2 - X1) / 2 ),
ST_MakePoint( X2 + (Y2 - Y1) / 2 , Y2 - (X2 - X1) / 2 ),
ST_MakePoint( X2 - (Y2 - Y1) / 2 , Y2 + (X2 - X1) / 2 ),
ST_MakePoint( X1 - (Y2 - Y1) / 2 , Y1 + (X2 - X1) / 2 )]
)
) Rectangle
FROM SEGMENT_LINE;
SQL Server 2012+
WITH /*RECURSIVE*/ SEGMENT_LINE AS (
SELECT
Line.STPointN(Line.STNumPoints()).STX X1, Line.STPointN(Line.STNumPoints()).STY Y1,
Line.STPointN(Line.STNumPoints()).STBuffer(200).STExteriorRing() Ring,
CASE WHEN Line.STPointN(Line.STNumPoints()).STBuffer(200).STExteriorRing().STIntersects(Line) = 1 THEN
Line.STPointN(Line.STNumPoints()).STBuffer(200).STExteriorRing().STIntersection(Line).STPointN(1).STX
ELSE
Line.STPointN(1).STX
END X2,
CASE WHEN Line.STPointN(Line.STNumPoints()).STBuffer(200).STExteriorRing().STIntersects(Line) = 1 THEN
Line.STPointN(Line.STNumPoints()).STBuffer(200).STExteriorRing().STIntersection(Line).STPointN(1).STY
ELSE
Line.STPointN(1).STY
END Y2,
CASE WHEN Line.STPointN(Line.STNumPoints()).STBuffer(200).STExteriorRing().STIntersects(Line) = 1 THEN
Line.STDifference(Line.STPointN(Line.STNumPoints()).STBuffer(200))
ELSE NULL END Line
FROM (VALUES(Geometry::STGeomFromText('LINESTRING(0 0 ,100 500 ,500 600 ,750 300 ,900 700 )',0)))A(Line)
UNION ALL
SELECT
Line.STPointN(Line.STNumPoints()).STX X1, Line.STPointN(Line.STNumPoints()).STY Y1,
Line.STPointN(Line.STNumPoints()).STBuffer(200).STExteriorRing() Ring,
CASE WHEN Line.STPointN(Line.STNumPoints()).STBuffer(200).STExteriorRing().STIntersects(Line) = 1 THEN
Line.STPointN(Line.STNumPoints()).STBuffer(200).STExteriorRing().STIntersection(Line).STPointN(1).STX
ELSE
Line.STPointN(1).STX
END X2,
CASE WHEN Line.STPointN(Line.STNumPoints()).STBuffer(200).STExteriorRing().STIntersects(Line) = 1 THEN
Line.STPointN(Line.STNumPoints()).STBuffer(200).STExteriorRing().STIntersection(Line).STPointN(1).STY
ELSE
Line.STPointN(1).STY
END Y2,
CASE WHEN Line.STPointN(Line.STNumPoints()).STBuffer(200).STExteriorRing().STIntersects(Line) = 1 THEN
Line.STDifference(Line.STPointN(Line.STNumPoints()).STBuffer(200))
ELSE NULL END Line
FROM SEGMENT_LINE
WHERE LINE IS NOT NULL
)
SELECT X1, Y1, X2, Y2, Ring,
Geometry::STGeomFromText(CONCAT('LINESTRING(',X1,' ',Y1,', ',X2,' ',Y2,')'),0) Line,
Geometry::STGeomFromText(CONCAT('POLYGON((',
X1 - (Y2 - Y1) / 2, ' ' , Y1 + (X2 - X1) / 2, ', ',
X1 + (Y2 - Y1) / 2, ' ' , Y1 - (X2 - X1) / 2, ', ',
X2 + (Y2 - Y1) / 2, ' ' , Y2 - (X2 - X1) / 2, ', ',
X2 - (Y2 - Y1) / 2, ' ' , Y2 + (X2 - X1) / 2, ', ',
X1 - (Y2 - Y1) / 2, ' ' , Y1 + (X2 - X1) / 2,
'))'),0) Rectangle
FROM SEGMENT_LINE;
For a line like this
we get rectangles as follows
It's not perfect, but as stated above if this is the sort of thing you are looking for then it can be improved.