// Calculates the maximum zoom level, with which both coordinates still fit into the given size
		public static int GetOptimalZoomLevel(Size size, BoundingBoxWGS84 box)
		{
			return GetOptimalZoomLevel(size, box.West, box.North, box.East, box.South);
		}
		private void MapPanel_MouseUp(object sender, MouseEventArgs e)
		{
			if(e.Button!=MouseButtons.Left) return;

			switch(CurrentAction)
			{
				case Action.Selection:
					{
						PointD centerTileCoord=GetTileIndex(ZoomLevel, X, Y);

						PointD startMouseTileCoord=centerTileCoord;
						startMouseTileCoord.X+=(selectionStartPosX-ClientSize.Width/2.0)/TileSize.Width;
						startMouseTileCoord.Y+=(selectionStartPosY-ClientSize.Height/2.0)/TileSize.Height;

						PointD endMouseTileCoord=centerTileCoord;
						endMouseTileCoord.X+=(e.X-ClientSize.Width/2.0)/TileSize.Width;
						endMouseTileCoord.Y+=(e.Y-ClientSize.Height/2.0)/TileSize.Height;

						PointD startMouseCoord=GetCoordinates(ZoomLevel, startMouseTileCoord.X, startMouseTileCoord.Y);
						PointD endMouseCoord=GetCoordinates(ZoomLevel, endMouseTileCoord.X, endMouseTileCoord.Y);
						MouseXWGS84=endMouseCoord.X;
						MouseYWGS84=endMouseCoord.Y;

						Selection=new BoundingBoxWGS84(startMouseCoord.X, startMouseCoord.Y, endMouseCoord.X, endMouseCoord.Y, MaxYCoordinate);

						CurrentAction=Action.None;
						selectionStartPosX=selectionStartPosY=0;
						selectionDragPosX=selectionDragPosY=0;

						Invalidate();
						if(SelectionChanged!=null) SelectionChanged(this, Selection);
					}
					break;
				case Action.Move:
					{
						moveDeltaX=moveStartPosX-e.X;
						moveDeltaY=moveStartPosY-e.Y;

						PointD tb=GetTileIndex(ZoomLevel, X, Y);
						tb.X+=(double)moveDeltaX/TileSize.Width;
						tb.Y+=(double)moveDeltaY/TileSize.Height;

						PointD coord=GetCoordinates(ZoomLevel, tb.X, tb.Y);
						X=coord.X;
						Y=coord.Y;

						CurrentAction=Action.None;
						moveStartPosX=moveStartPosY=0;
						moveDeltaX=moveDeltaY=0;

						Invalidate();
						if(PositionChanged!=null) PositionChanged(this, X, Y);

						if(!wasMoveDrag&&NonDragingMouseClick!=null) NonDragingMouseClick(this, MouseXWGS84, MouseYWGS84);
					}
					break;
				case Action.SelectionMove:
				case Action.SelectionSizeWest:
				case Action.SelectionSizeNorth:
				case Action.SelectionSizeEast:
				case Action.SelectionSizeSouth:
					{
						PointD selectionNWTileCoord=GetTileIndex(ZoomLevel, Selection.West, Selection.North);
						PointD selectionSETileCoord=GetTileIndex(ZoomLevel, Selection.East, Selection.South);

						PointD startMouseTileCoord=selectionNWTileCoord;
						if(CurrentAction==Action.SelectionSizeWest||CurrentAction==Action.SelectionMove)
							startMouseTileCoord.X+=((double)e.X-selectionStartPosX)/TileSize.Width;
						if(CurrentAction==Action.SelectionSizeNorth||CurrentAction==Action.SelectionMove)
							startMouseTileCoord.Y+=((double)e.Y-selectionStartPosY)/TileSize.Height;

						PointD endMouseTileCoord=selectionSETileCoord;
						if(CurrentAction==Action.SelectionSizeEast||CurrentAction==Action.SelectionMove)
							endMouseTileCoord.X+=((double)e.X-selectionStartPosX)/TileSize.Width;
						if(CurrentAction==Action.SelectionSizeSouth||CurrentAction==Action.SelectionMove)
							endMouseTileCoord.Y+=((double)e.Y-selectionStartPosY)/TileSize.Height;

						PointD startMouseCoord=GetCoordinates(ZoomLevel, startMouseTileCoord.X, startMouseTileCoord.Y);
						PointD endMouseCoord=GetCoordinates(ZoomLevel, endMouseTileCoord.X, endMouseTileCoord.Y);

						PointD mouseCoord=GetCoordinates(ZoomLevel, e.X, e.Y);
						MouseXWGS84=mouseCoord.X;
						MouseYWGS84=mouseCoord.Y;

						Selection=new BoundingBoxWGS84(startMouseCoord.X, startMouseCoord.Y, endMouseCoord.X, endMouseCoord.Y, MaxYCoordinate);

						CurrentAction=Action.None;
						selectionStartPosX=selectionStartPosY=0;
						selectionDragPosX=selectionDragPosY=0;

						Invalidate();
						if(SelectionChanged!=null) SelectionChanged(this, Selection);
					}
					break;
			}
		}
		public void ZoomToBoundingBox(BoundingBoxWGS84 bbox)
		{
			if(bbox==null) return;
			int zoomLevel=GetOptimalZoomLevel(ClientSize, bbox);
			ZoomLevel=zoomLevel-1;

			X=(bbox.West+bbox.East)/2;
			Y=(bbox.North+bbox.South)/2;

			if(PositionChanged!=null) PositionChanged(this, X, Y);
		}