Skip to content

GLMapBBoxAddPoint bug when crossing GLMapPointMax x line #1

@guidove

Description

@guidove

Scenario:

  • We have an original bbox (blue box) that's positioned just to the left of GLMapPointMax
  • We want to add a GLMapPoint that's just to the right of GLMapPointMax

Expected result: A slightly bigger bbox (green bbox) with the same origin and size slightly increased in x-direction to include the added point
Actual result: A huge bbox (red bbox) covering almost entire earth with point.x as origin.x.

Screenshot 2024-03-15 at 8 09 46

This huge bbox results in not being able to center and zoom the map correctly, because mapView.mapZoom(for: bbox) returns wrong value and center of bbox also is incorrect.

Solution:

 extension GLMapBBox {   
    mutating func join(point: GLMapPoint) {

        if self.size.x < 0 && self.size.y < 0 {
            self.size = GLMapPoint.zero
            if point.x == 0 {
                /// If the x position of the first point that we are adding to an empty bbox is exactly on 0, we shift it just a little bit so that it's just left of GLMapPointMax
                /// This is because the rest of the method won't work when origin.x is 0 (see code comments below)
                self.origin.x = Double(GLMapPointMax) - 1
                self.origin.y = point.y
            }
            else {
                self.origin = point
            }
        }

        else {
            if (point.x < self.origin.x) {
                
                /// There are two scenarios here
                /// Scenario 1: point we are adding is on the same side of the GLMapPointMax x-line (maxLine)
                /// Scenario 2: point we are adding is on the other side of the maxLine (the right side, while bbox is on the left side)
                /// To account for this, we assume that, if the difference between point.x and self.origin.x is bigger than GLMapPointMax/2 that we are dealing with this scenario 2.
                ///
                
                if (self.origin.x - point.x) > Double(GLMapPointMax)/2 {
                    /// Scenario 2
                    /// We are adding a point that's on the right side of the maxLine, while bbox is on the left side.
                    /// In this case we do nothing with the origin. It stays the same. However size becomes bigger, but only if point falls outside (to the right of current size)
                    self.size.x = max(self.size.x, Double(GLMapPointMax) - self.origin.x + point.x)
                }
                else {
                    /// Scenario 1
                    /// New point becomes origin of bbox, and size of bbox increase accordingly
                    self.size.x = self.size.x + self.origin.x - point.x
                    self.origin.x = point.x
                }
            }
            else if (point.x > self.origin.x + self.size.x) {

                /// There are two scenarios here
                /// Scenario 3: point we are adding is on the same side of the maxLine
                /// Scenario 4: point we are adding is on the other side of the maxLine (the left side, while bbox is on the right side)
                /// To account for this, we assume that, if the difference between point.x and (self.origin.x + self.size.x) is bigger than GLMapPointMax/2 that we are dealing with this scenario 4.

                if (point.x - (self.origin.x + self.size.x)) > Double(GLMapPointMax)/2 {
                    /// Scenario 4
                    /// We are adding a point that's left of the maxLine, while all of bbox was right of maxLine so far
                    self.origin.x = point.x
                    self.size.x = self.size.x + Double(GLMapPointMax) - point.x
                }
                else {
                    /// Scenario 3
                    /// We increase the size because new point is to the right of origin
                    self.size.x = point.x - self.origin.x
                }
            }
            
            if (point.y < self.origin.y) {
                self.size.y += self.origin.y - point.y
                self.origin.y = point.y
            }
            else if (point.y > self.origin.y + self.size.y) {
                self.size.y = point.y - self.origin.y
            }
        }
    }


    mutating func join(bbox: GLMapBBox) {
        if !bbox.isEmpty {
            self.join(point: bbox.origin)
            self.join(point: GLMapPoint(x: bbox.origin.x + bbox.size.x, y: bbox.origin.y + bbox.size.y))
        }
    }

}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions