adjustCenterIfOutsideMaxBounds method

LatLng? adjustCenterIfOutsideMaxBounds(
  1. LatLng testCenter,
  2. double testZoom,
  3. LatLngBounds maxBounds
)

Implementation

LatLng? adjustCenterIfOutsideMaxBounds(
    LatLng testCenter, double testZoom, LatLngBounds maxBounds) {
  LatLng? newCenter;

  final swPixel = project(maxBounds.southWest!, testZoom);
  final nePixel = project(maxBounds.northEast!, testZoom);

  final centerPix = project(testCenter, testZoom);

  final halfSizeX = size.x / 2;
  final halfSizeY = size.y / 2;

  // Try and find the edge value that the center could use to stay within
  // the maxBounds. This should be ok for panning. If we zoom, it is possible
  // there is no solution to keep all corners within the bounds. If the edges
  // are still outside the bounds, don't return anything.
  final leftOkCenter = math.min(swPixel.x, nePixel.x) + halfSizeX;
  final rightOkCenter = math.max(swPixel.x, nePixel.x) - halfSizeX;
  final topOkCenter = math.min(swPixel.y, nePixel.y) + halfSizeY;
  final botOkCenter = math.max(swPixel.y, nePixel.y) - halfSizeY;

  double? newCenterX;
  double? newCenterY;

  var wasAdjusted = false;

  if (centerPix.x < leftOkCenter) {
    wasAdjusted = true;
    newCenterX = leftOkCenter;
  } else if (centerPix.x > rightOkCenter) {
    wasAdjusted = true;
    newCenterX = rightOkCenter;
  }

  if (centerPix.y < topOkCenter) {
    wasAdjusted = true;
    newCenterY = topOkCenter;
  } else if (centerPix.y > botOkCenter) {
    wasAdjusted = true;
    newCenterY = botOkCenter;
  }

  if (!wasAdjusted) {
    return testCenter;
  }

  final newCx = newCenterX ?? centerPix.x;
  final newCy = newCenterY ?? centerPix.y;

  // Have a final check, see if the adjusted center is within maxBounds.
  // If not, give up.
  if (newCx < leftOkCenter ||
      newCx > rightOkCenter ||
      newCy < topOkCenter ||
      newCy > botOkCenter) {
    return null;
  } else {
    newCenter = unproject(CustomPoint(newCx, newCy), testZoom);
  }

  return newCenter;
}