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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions